2010-12-07 8 views
5

iOS için bir frekans algılama uygulaması üzerinde çalışıyorum ve mikrofondan ses örnekleri ile kullanıcı tanımlı bir AudioBufferList doldurma sorunu yaşıyorum.Uzak I/O ile kayıt, AudioUnitRender -50 dönüş kodu

InputCallback yöntemimde AudioUnitRender'ı aradığımda -50 dönüş kodunu alıyorum. Bunun benim parametrelerimden birinin geçersiz olduğu anlamına geldiğini düşünüyorum. Sanırım AudioBufferList, ama neyin yanlış olduğunu anlayamadım. Sanırım ayarladıktan sonra ASBD'imde belirttiğim veri formatıyla eşleşiyor. Aşağıda

uzak G/Ç kurulumu ve fonksiyon ı yanlış olabilir inanıyorum çağırır:

ASBD:

size_t bytesPerSample = sizeof(AudioUnitSampleType); 
AudioStreamBasicDescription localStreamFormat = {0}; 
localStreamFormat.mFormatID = kAudioFormatLinearPCM; 
localStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; 
localStreamFormat.mBytesPerPacket = bytesPerSample; 
localStreamFormat.mBytesPerFrame = bytesPerSample; 
localStreamFormat.mFramesPerPacket = 1; 
localStreamFormat.mBitsPerChannel = 8 * bytesPerSample; 
localStreamFormat.mChannelsPerFrame = 2; 
localStreamFormat.mSampleRate = sampleRate; 

InputCallback Bildirgesi:

err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_SetInputCallback, 
          kAudioUnitScope_Input, 
          kOutputBus, &callbackStruct, sizeof(callbackStruct)); 

AudioBufferList Bildirgesi:

// Allocate AudioBuffers 
bufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer)); 
bufferList->mNumberBuffers = 1; 
bufferList->mBuffers[0].mNumberChannels = 2; 

bufferList->mBuffers[0].mDataByteSize = 1024; 
bufferList->mBuffers[0].mData = calloc(256, sizeof(uint32_t)); 

InputCallback Fonksiyonu:

AudioUnit rioUnit = THIS->ioUnit; 
OSStatus renderErr; 
UInt32 bus1 = 1; 
renderErr = AudioUnitRender(rioUnit, ioActionFlags, inTimeStamp, bus1, inNumberFrames, THIS->bufferList); 

birkaç nokta not:

  • /Ç veri 8.24 bitlik sabit nokta ben, Örnek Oranı = uzaktan I kurallı biçimi yana 22.050 Hz
  • olduğunu Numunelerin her biri 32 bit olduğunu varsayarak (veya 4 bayt). İmzasız bir int 4 bayt olduğundan, ses arabamı ayırmak için bunu kullanıyorum.
  • Ses veri akışını yalnızca giriş yerine PassThru olarak uygularsam, sesi doğru şekilde işitmek için aynı kodu alabilirim.
  • Uzak I/O üzerinde zaten Michael Tyson's blog post'a baktım. Yaptığım şeyden farklı bir şey görmedim.

Tekrar teşekkürler, hepiniz harikasınız!

Demetri

+0

Sonunda bahsettiğim frekans algılama uygulamasını bitirdim. İlgilenenler için kaynak kodu ile birlikte bir yazdım. DÜZENLEME: bağlantı ... http: //sleepyleaf.com/2011/01/25/pitch-detection-in-ios-4-x/ – irtemed88

+0

Belirtilen hiçbir Kod bulunamadı .. Links sleepyleaf.com/2011/ 01/25/pitch-detection-in-ios-4-x - irtemed88 –

+0

Hata! Üzgünüm, etki alanımı güncelledim. Yeni bağlantı: http://demetrimiller.com/2011/01/25/pitch-detection-in-ios-4-x/ – irtemed88

cevap

4

Çerçeve başına 2 kanalınız varsa, çerçevenin boyutu olarak bytesPerSample ürününe sahip olamazsınız. terminoloji kafa biraz yana:

  • bir örnek bir dalga formu içinde belirli bir konumda bulunan, tek bir değerdir
  • belirli bir ses akışı ile ilişkili veriler belirtmektedir bir kanal, yani, sol/stereo için doğru kanal, mono için tek kanal, vb.
  • bir çerçeve bir dalga formu
  • belirli bir pozisyon için tüm kanallar için örnekleri içeren bir paket içeren bir ya da

Temel olarak, mBytesPerFrame için bytesPerSample * mChannelsPerFrame kullanmak için gereken daha fazla kare ve mBytesPerPacket için mBytesPerFrame * mFramesPerPacket kullanın.

Ayrıca, örnek boyutunuz için 32 bit kullandığınızı fark ettim. Bunu gerçekten yapmak isteyip istemediğinizden emin değilim - genellikle 16 bitlik örnekleri kullanarak ses kaydetmek istiyorsunuz. 16 ve 32 bit ses arasındaki ses farkı çoğu dinleyicinin işitmesi neredeyse imkansızdır (ortalama CD 44.1kHz, 16-bit PCM'de yönetilir) ve size I/O ve depolama maliyetlerinin% 50'sini verecektir.

+0

Ok teşekkürler! Biraz kafam karışmıştı çünkü dokümanlar kanonik ses örneği formatının 8.24 bit sabit nokta olduğunu gösteriyor. Kullanmam gereken format olduğunu ve 32 bit olduğunu varsaydım. 16-bit örnekler kullanıyorum, bu örnek türleri 16 bit imzalı ints anlamına mı geliyor? – irtemed88

+0

Evet, 16 bit, verilerinizin teknik olarak imzalanmış bir şort veya "SInt16" olarak depolandığı anlamına gelir. Ve evet, 8-24 bit en yaygın aralığı temsil ederken, neredeyse tüm günlük kayıtlar 16 bit kullanır. 8 bitlik sesler berbat ve kimse 16 ile 24 arasındaki farkı duyamaz;) –

0

farklardan biri Tyson'ın RemoteIO blog yazısı doğrusal PCM numune başına 2 bayt kullanır. Yani bu bir biçim uyumsuz hata olabilir.

+0

Biçim için kAudioFormatFlagsAudioUnitCanonical'i ayarladığımdan bu sorunun neden sorun olacağından emin değilim bayraklar. Belgeler bu 8.24 bit sabit nokta biçimidir. – irtemed88

0

bufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer)); hattı da yanlıştır. AudioBuffer, AudioBufferList'ten daha küçük olduğundan, yeterli bellek ayırmaz.