組み込みのオーディオ入力からオーディオをキャプチャし、ソケットからの読み取りのように、要求されたときに入力された生のサンプル値(.wavのように)をリアルタイムで読み取ることができる最も簡単な方法は何ですか。
うまくいけば、Appleのフレームワークの1つ(オーディオキュー)を使用するコード。ドキュメントはあまり明確ではなく、私が必要としているのは非常に基本的なものです。
組み込みのオーディオ入力からオーディオをキャプチャし、ソケットからの読み取りのように、要求されたときに入力された生のサンプル値(.wavのように)をリアルタイムで読み取ることができる最も簡単な方法は何ですか。
うまくいけば、Appleのフレームワークの1つ(オーディオキュー)を使用するコード。ドキュメントはあまり明確ではなく、私が必要としているのは非常に基本的なものです。
これにはAudioQueueFrameworkを試してください。主に次の3つの手順を実行する必要があります。
ステップ3では、AudioQueueGetProperty()を使用して着信オーディオデータを分析する機会があります。
おおまかに次のようになります。
static void HandleAudioCallback (void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc) {
// Here you examine your audio data
}
static void StartRecording() {
// now let's start the recording
AudioQueueNewInput (&aqData.mDataFormat, // The sampling format how to record
HandleAudioCallback, // Your callback routine
&aqData, // e.g. AudioStreamBasicDescription
NULL,
kCFRunLoopCommonModes,
0,
&aqData.mQueue); // Your fresh created AudioQueue
AudioQueueStart(aqData.mQueue,
NULL);
}
AudioQueueを開始および停止する方法と、必要なすべてのオブジェクトを正しくセットアップする方法の詳細については、AppleAudioQueueServicesプログラミングガイドをお勧めします。
また、AppleのデモプログラムSpeakHereを詳しく調べることもできます。しかし、これは私見ですが、最初は少し混乱します。
それはあなたがそれをどのように「リアルタイム」必要とするかに依存します
非常に鮮明なものが必要な場合は、一番下のレベルに降りて、オーディオユニットを使用してください。これは、INPUTコールバックを設定することを意味します。これが発生した場合は、独自のバッファを割り当ててから、マイクからの音声を要求する必要があることを忘れないでください。
つまり、パラメータにバッファポインタが存在することに騙されないでください...これは、Appleが入力コールバックとレンダリングコールバックに同じ関数宣言を使用しているためにのみ存在します。
これが私のプロジェクトの1つからのペーストです:
OSStatus dataArrivedFromMic(
void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * dummy_notused )
{
OSStatus status;
RemoteIOAudioUnit* unitClass = (RemoteIOAudioUnit *)inRefCon;
AudioComponentInstance myUnit = unitClass.myAudioUnit;
AudioBufferList ioData;
{
int kNumChannels = 1; // one channel...
enum {
kMono = 1,
kStereo = 2
};
ioData.mNumberBuffers = kNumChannels;
for (int i = 0; i < kNumChannels; i++)
{
int bytesNeeded = inNumberFrames * sizeof( Float32 );
ioData.mBuffers[i].mNumberChannels = kMono;
ioData.mBuffers[i].mDataByteSize = bytesNeeded;
ioData.mBuffers[i].mData = malloc( bytesNeeded );
}
}
// actually GET the data that arrived
status = AudioUnitRender( (void *)myUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
& ioData );
// take MONO from mic
const int channel = 0;
Float32 * outBuffer = (Float32 *) ioData.mBuffers[channel].mData;
// get a handle to our game object
static KPRing* kpRing = nil;
if ( ! kpRing )
{
//AppDelegate * appDelegate = [UIApplication sharedApplication].delegate;
kpRing = [Game singleton].kpRing;
assert( kpRing );
}
// ... and send it the data we just got from the mic
[ kpRing floatsArrivedFromMic: outBuffer
count: inNumberFrames ];
return status;
}