objective c - Example of using Audio Queue Services -


i seeking example of using audio queue services.

i create sound using mathematical equation , hear it.

here's code generating sound function. i'm assuming know how use audioqueue services, set audiosession, , start , stop audio output queue.

here's snippet setting , starting output audioqueue:

// preferred sample rate (8,000 hz on iphone, 44,100 hz on ipod touch) size = sizeof(samplerate); err = audiosessiongetproperty (kaudiosessionproperty_currenthardwaresamplerate, &size, &samplerate); if (err != noerr) nslog(@"audiosessiongetproperty(kaudiosessionproperty_currenthardwaresamplerate) error: %d", err);  //nslog (@"current hardware sample rate: %1.0f", samplerate);  bool ishighsamplerate = (samplerate > 16000); int bufferbytesize; audioqueuebufferref buffer;  // set stream format fields audiostreambasicdescription streamformat; streamformat.msamplerate = samplerate; streamformat.mformatid = kaudioformatlinearpcm; streamformat.mformatflags = klinearpcmformatflagissignedinteger | klinearpcmformatflagispacked; streamformat.mbitsperchannel = 16; streamformat.mchannelsperframe = 1; streamformat.mbytesperpacket = 2 * streamformat.mchannelsperframe; streamformat.mbytesperframe = 2 * streamformat.mchannelsperframe; streamformat.mframesperpacket = 1; streamformat.mreserved = 0;  // new output queue ---- playback ---- if (isplaying == no) {     err = audioqueuenewoutput (&streamformat, audioengineoutputbuffercallback, self, nil, nil, 0, &outputqueue);     if (err != noerr) nslog(@"audioqueuenewoutput() error: %d", err);      // enqueue buffers     //outputfrequency = 0.0;     outputbufferstorewrite = 3;     bufferbytesize = (samplerate > 16000)? 2176 : 512; // 40.5 hz : 31.25 hz      (i=0; i<3; i++) {         err = audioqueueallocatebuffer (outputqueue, bufferbytesize, &buffer);          if (err == noerr) {             [self generatetone: buffer];             err = audioqueueenqueuebuffer (outputqueue, buffer, 0, nil);             if (err != noerr) nslog(@"audioqueueenqueuebuffer() error: %d", err);         } else {             nslog(@"audioqueueallocatebuffer() error: %d", err);              return;         }     }      // start playback     isplaying = yes;     err = audioqueuestart(outputqueue, nil);     if (err != noerr) { nslog(@"audioqueuestart() error: %d", err); isplaying= no; return; } } else {     nslog (@"error: audio playing back."); } 

here's part generates tone:

// audioqueue output queue callback. void audioengineoutputbuffercallback (void *inuserdata, audioqueueref inaq, audioqueuebufferref inbuffer) {     audioengine *engine = (audioengine*) inuserdata;     [engine processoutputbuffer:inbuffer queue:inaq]; }  - (void) processoutputbuffer: (audioqueuebufferref) buffer queue:(audioqueueref) queue {     osstatus err;     if (isplaying == yes) {         [outputlock lock];         if (outputbufferstorewrite > 0) {             outputbufferstorewrite--;             [self generatetone:buffer];         }         err = audioqueueenqueuebuffer(queue, buffer, 0, null);         if (err == 560030580) { // queue not active due music being started or other reasons             isplaying = no;         } else if (err != noerr) {             nslog(@"audioqueueenqueuebuffer() error %d", err);         }         [outputlock unlock];     } else {         err = audioqueuestop (queue, no);         if (err != noerr) nslog(@"audioqueuestop() error: %d", err);     } }  -(void) generatetone: (audioqueuebufferref) buffer {     if (outputfrequency == 0.0) {         memset(buffer->maudiodata, 0, buffer->maudiodatabytescapacity);         buffer->maudiodatabytesize = buffer->maudiodatabytescapacity;     } else {         // make buffer length multiple of wavelength output frequency.         int samplecount = buffer->maudiodatabytescapacity / sizeof (sint16);         double bufferlength = samplecount;         double wavelength = samplerate / outputfrequency;         double repetitions = floor (bufferlength / wavelength);         if (repetitions > 0.0) {             samplecount = round (wavelength * repetitions);         }          double      x, y;         double      sd = 1.0 / samplerate;         double      amp = 0.9;         double      max16bit = shrt_max;         int i;         sint16 *p = buffer->maudiodata;          (i = 0; < samplecount; i++) {             x = * sd * outputfrequency;             switch (outputwaveform) {                 case ksine:                      y = sin (x * 2.0 * m_pi);                     break;                 case ktriangle:                     x = fmod (x, 1.0);                     if (x < 0.25)                         y = x * 4.0; // 0.0 1.0                     else if (x < 0.75)                         y = (1.0 - x) * 4.0 - 2.0; // down 1.0 -1.0                     else                          y = (x - 1.0) * 4.0; // -1.0 0.0                     break;                 case ksawtooth:                     y  = 0.8 - fmod (x, 1.0) * 1.8;                     break;                 case ksquare:                     y = (fmod(x, 1.0) < 0.5)? 0.7: -0.7;                     break;                 default: y = 0; break;             }             p[i] = y * max16bit * amp;         }          buffer->maudiodatabytesize = samplecount * sizeof (sint16);     } } 

something watch out callback called on non-main thread, have practice thread safety locks, mutexs, or other techniques.


Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -