views:

535

answers:

3

I've seen countless infos on how to play a sound file, but how can I generate a specific audio tone (or several) at given Hertz in cocoa touch?

+1  A: 

One simple way: You've found sample code for playing audio files. Your audio file can be a sine wave. You can change the playback rate.

There are other ways if you go to the work of managing your own buffers.

Nosredna
+1  A: 

The low-level approach is using CoreAudio with the kAudioUnitSubType_RemoteIO and kAudioUnitSubType_AU3DMixerEmbedded audio units.
The SDK comes with some built-in CoreAudio units - you can't implement your own yet.
A good API to connect those units is AUGraph.
As you can't implement your own audio units that render a sinewave, you will have to use render-callbacks and attach them to the input bus of your mixer unit.
Fill out a AURenderCallbackStruct and connect it to your Graph with AUGraphSetNodeInputCallback

To generate the actual sinewave you could use something like this as render callback (the code is actually for the Mac but the render callback should work on the phone)

weichsel
A: 

Something along the lines of this pseudo-code, rather than reading from an audio file buffer:

class osc {
...
    double phase; /* init to 0 (0 deg) */
...
};

void osc::render(double* dest, uint samples) {

    const double frequency(1000.0); /* 1000 Hz test tone frequency */
    const double sr(getDeviceSampleRate());

    const double two_pi(M_PI * 2.0);

    const double phaseAccumIncN(freq / sr); /* in the range [0...1] */
    const double phaseAccumInc(phaseAccumIncN * two_pi); /* put it in the range [0...two_pi] */

    while (samples--) {

     *dest++ = sin(this->phase);

     this->phase += phaseAccumInc;

     while (two_pi < this->phase) {
      this->phase -= two_pi;
     }
    }

}
Justin