2010-07-24 17 views
15

मैं ऑडियो कतार सेवाओं का उपयोग करने का एक उदाहरण ढूंढ रहा हूं।ऑडियो कतार सेवाओं का उपयोग करने का उदाहरण

मैं गणितीय समीकरण का उपयोग करके ध्वनि बनाना चाहता हूं और फिर इसे सुनना चाहता हूं।

उत्तर

25

यहां एक फ़ंक्शन से ध्वनि उत्पन्न करने के लिए मेरा कोड है। मुझे लगता है कि आप ऑडियो क्यूई सेवाओं का उपयोग कैसे करें, ऑडियो सत्र स्थापित करें, और एक ऑडियो आउटपुट कतार ठीक से शुरू करें और रोकें।

// Get the 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 up 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 
    for (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 is already playing back."); 
} 

यहाँ बात यह है कि स्वर उत्पन्न करता है: बाहर देखने के लिए है कि अपने कॉलबैक बुलाया जाएगा

// 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 is not active due to 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 the buffer length a multiple of the wavelength for the 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; 

     for (i = 0; i < sampleCount; i++) { 
      x = i * 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; // up 0.0 to 1.0 
        else if (x < 0.75) 
         y = (1.0 - x) * 4.0 - 2.0; // down 1.0 to -1.0 
        else 
         y = (x - 1.0) * 4.0; // up -1.0 to 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); 
    } 
} 

कुछ

यहाँ की स्थापना और एक आउटपुट AudioQueue शुरू करने के लिए एक टुकड़ा है एक गैर-मुख्य धागे पर, इसलिए आपको ताले, म्यूटेक्स या अन्य तकनीकों के साथ थ्रेड सुरक्षा का अभ्यास करना होगा।

+0

क्या आप अपना कोड साझा कर सकते हैं? –

7

उच्च स्तर: का उपयोग AVAudioPlayer https://github.com/hollance/AVBufferPlayer

मेड का स्तर: ऑडियो कतारों trailsinthesand.com/exploring-iphone-audio-part-1/ आप अच्छी तरह से जा रहा हो जाता है। नोट: मैंने http को हटा दिया है, इसलिए पुराना लिंक वहां हो सकता है, लेकिन यह एक बुरी साइट पर सीधे जाता है, इसलिए यह स्पष्ट रूप से बदल गया है।

कम का स्तर: वैकल्पिक रूप से, आप एक स्तर नीचे ड्रॉप और ऑडियो इकाइयों के साथ यह कर सकते हैं: http://cocoawithlove.com/2010/10/ios-tone-generator-introduction-to.html

+2

सिंथ में ऑडियो कतार: https://github.com/hollance/AudioBufferPlayer –

+0

आपके उदाहरण ने मुझे बहुत मदद की, धन्यवाद फिर से – Amitg2k12

+0

trailsinthesand.com अब एक वयस्क वेबसाइट – blwinters

9

इस से @lucius

void SetupAudio() 
    { 
     AudioSession.Initialize(); 
     AudioSession.Category = AudioSessionCategory.MediaPlayback; 

     sampleRate = AudioSession.CurrentHardwareSampleRate; 
     var format = new AudioStreamBasicDescription() { 
      SampleRate = sampleRate, 
      Format = AudioFormatType.LinearPCM, 
      FormatFlags = AudioFormatFlags.LinearPCMIsSignedInteger | AudioFormatFlags.LinearPCMIsPacked, 
      BitsPerChannel = 16, 
      ChannelsPerFrame = 1, 
      BytesPerFrame = 2, 
      BytesPerPacket = 2, 
      FramesPerPacket = 1, 
     }; 

     var queue = new OutputAudioQueue (format); 
     var bufferByteSize = (sampleRate > 16000)? 2176 : 512; // 40.5 Hz : 31.25 Hz 
     var buffers = new AudioQueueBuffer* [numBuffers]; 
     for (int i = 0; i < numBuffers; i++){ 
      queue.AllocateBuffer (bufferByteSize, out buffers [i]); 
      GenerateTone (buffers [i]); 
      queue.EnqueueBuffer (buffers [i], null); 
     } 
     queue.OutputCompleted += (object sender, OutputCompletedEventArgs e) => { 
      queue.EnqueueBuffer (e.UnsafeBuffer, null); 
     }; 

     queue.Start(); 
     return true; 
    } 

यह वह जगह है ही नमूना के सी # का उपयोग कर एक संस्करण है स्वर जनरेटर:

0:

void GenerateTone (AudioQueueBuffer *buffer) 
    { 
     // Make the buffer length a multiple of the wavelength for the output frequency. 
     uint sampleCount = buffer->AudioDataBytesCapacity/2; 
     double bufferLength = sampleCount; 
     double wavelength = sampleRate/outputFrequency; 
     double repetitions = Math.Floor (bufferLength/wavelength); 
     if (repetitions > 0) 
      sampleCount = (uint)Math.Round (wavelength * repetitions); 

     double  x, y; 
     double  sd = 1.0/sampleRate; 
     double  amp = 0.9; 
     double  max16bit = Int16.MaxValue; 
     int i; 
     short *p = (short *) buffer->AudioData; 

     for (i = 0; i < sampleCount; i++) { 
      x = i * sd * outputFrequency; 
      switch (outputWaveForm) { 
       case WaveForm.Sine: 
        y = Math.Sin (x * 2.0 * Math.PI); 
        break; 
       case WaveForm.Triangle: 
        x = x % 1.0; 
        if (x < 0.25) 
         y = x * 4.0; // up 0.0 to 1.0 
        else if (x < 0.75) 
         y = (1.0 - x) * 4.0 - 2.0; // down 1.0 to -1.0 
        else 
         y = (x - 1.0) * 4.0; // up -1.0 to 0.0 
        break; 
       case WaveForm.Sawtooth: 
        y = 0.8 - (x % 1.0) * 1.8; 
        break; 
       case WaveForm.Square: 
        y = ((x % 1.0) < 0.5)? 0.7: -0.7; 
        break; 
       default: y = 0; break; 
      } 
      p[i] = (short)(y * max16bit * amp); 
     } 
     buffer->AudioDataByteSize = sampleCount * 2; 
    } 
} 

आप भी इन परिभाषाओं चाहते

संबंधित मुद्दे