具有可变振荡模式的iOS音调生成器 [英] iOS Tone Generator with variable Oscillation Patterns

查看:173
本文介绍了具有可变振荡模式的iOS音调生成器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Tone Generator应用程序,该应用程序基于"Slider Value"(频率)来生成频率的声音.该应用程序的这一部分工作正常.我正在使用

I have a Tone Generator Application that generates a tone based on Slider Value for frequency. This part of the application works fine. I'm redering tone using

#import <AudioToolbox/AudioToolbox.h>

OSStatus RenderTone(
void *inRefCon, 
AudioUnitRenderActionFlags  *ioActionFlags, 
const AudioTimeStamp        *inTimeStamp, 
UInt32                      inBusNumber, 
UInt32                      inNumberFrames, 
AudioBufferList             *ioData)

{
// Fixed amplitude is good enough for our purposes
const double amplitude = 0.25;

// Get the tone parameters out of the view controller
ToneGeneratorViewController *viewController =
    (ToneGeneratorViewController *)inRefCon;
double theta = viewController->theta;
double theta_increment = 2.0 * M_PI * viewController->frequency / viewController-    >sampleRate;

// This is a mono tone generator so we only need the first buffer
const int channel = 0;
Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;

// Generate the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++) 
{
    buffer[frame] = sin(theta) * amplitude;

    theta += theta_increment;
    if (theta > 2.0 * M_PI)
    {
        theta -= 2.0 * M_PI;
    }
}

// Store the theta back in the view controller
viewController->theta = theta;

return noErr;
}



- (void)createToneUnit
{
// Configure the search parameters to find the default playback output unit
// (called the kAudioUnitSubType_RemoteIO on iOS but
// kAudioUnitSubType_DefaultOutput on Mac OS X)
AudioComponentDescription defaultOutputDescription;
defaultOutputDescription.componentType = kAudioUnitType_Output;
defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
defaultOutputDescription.componentFlags = 0;
defaultOutputDescription.componentFlagsMask = 0;

// Get the default playback output unit
AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);
NSAssert(defaultOutput, @"Can't find default output");

// Create a new unit based on this that we'll use for output
OSErr err = AudioComponentInstanceNew(defaultOutput, &toneUnit);
NSAssert1(toneUnit, @"Error creating unit: %ld", err);

// Set our tone rendering function on the unit
AURenderCallbackStruct input;
input.inputProc = RenderTone;
input.inputProcRefCon = self;
err = AudioUnitSetProperty(toneUnit, 
    kAudioUnitProperty_SetRenderCallback, 
    kAudioUnitScope_Input,
    0, 
    &input, 
    sizeof(input));
NSAssert1(err == noErr, @"Error setting callback: %ld", err);

// Set the format to 32 bit, single channel, floating point, linear PCM
const int four_bytes_per_float = 4;
const int eight_bits_per_byte = 8;
AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags =
    kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
streamFormat.mBytesPerPacket = four_bytes_per_float;
streamFormat.mFramesPerPacket = 1;  
streamFormat.mBytesPerFrame = four_bytes_per_float;     
streamFormat.mChannelsPerFrame = 1; 
streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
err = AudioUnitSetProperty (toneUnit,
    kAudioUnitProperty_StreamFormat,
    kAudioUnitScope_Input,
    0,
    &streamFormat,
    sizeof(AudioStreamBasicDescription));
NSAssert1(err == noErr, @"Error setting stream format: %ld", err);
}

现在,我需要在诸如Dog Whistler Application之类的应用程序中修改模式.谁能告诉我按照此源代码修改波型需要做些什么?

Now I need to modify the patterns in the application like Dog Whistler Application. Can anyone tell me what things do I need do to modify the wave patterns following this source code?

预先感谢

推荐答案

您可能需要为每个特定模式使用不同的RenderTone实现.您代码中的实现会产生一个没有调制的采样纯正弦波.您可以生成各种模式,这取决于您的需求,您将实现什么.

You would probably need different RenderTone implementations for each specific pattern. The implementation in your code produces a sampled pure sinusoidal wave with no modulation. There are various patterns you could generate, it depends on your needs what will you implement.

例如,产生较短或较长的蜂鸣声将要求您在"for"循环中针对循环中一定数量的正弦曲线生成沉默"(将0-s写入缓冲区),然后生成再次进行窦性采样,然后再次静音...(这就像斩波信号一样)

For example, generating shorter or longer beeps would require that you generate 'silence' (write 0-s to the buffer) in your 'for' loop for the sinusoidal for a certain number of frames within the loop and then generate the sinusiodal samples again and then silence again... (this is like chopping the signal)

您还可以通过用另一个正弦信号(频率要低得多)计算出的因子来缩放样本值,从而进行幅度调制(颤音效果).

You could also make an amplitude modulation (tremolo effect) by scaling the sample values with a factor computed with another sine signal (with much lower frequency).

另一个示例是通过调制生成的样本的频率(颤音效果)来产生警笛声"(实质上是您的变量theta_increment的值),并且还根据低频信号.或者,只需使用两个不同的值就可以交替使用,就像上面的哔"声效果一样.

Another example would be to produce a 'police siren' sound by modulating the frequency of the generated sample (vibrato effect), essentially the value of your variable theta_increment, also according to a low frequency signal. Or, simply using two different values for it alternating as with the 'beep' effect above.

希望,这会有所帮助.

这篇关于具有可变振荡模式的iOS音调生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆