In dem Bemühen, in MacOS-Programmierung zu gelangen, versuche ich ein einfaches Programm zu machen, das Audio von einem Eingabegerät aufnehmen würde (zB das eingebaute Mikrofon auf meinem MacBook Pro) . Ich habe ein Objective-C Cocoa-Projekt in Xcode erstellt und der Code ist eine leicht angepasste Version von this tutorial from developer.apple.com.Eingangswarteschlange Callback, aber keine Daten
Hier ist mein Code:
// AppDelegate.m:
#include <AudioToolbox/AudioToolbox.h>
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
struct AQRecorderState S;
#define PRINT_R do{\
printf("%d: r = %d\n",__LINE__, r);\
}while(0)
AudioStreamBasicDescription *fmt = &S.mDataFormat;
fmt->mFormatID = kAudioFormatLinearPCM;
fmt->mSampleRate = 44100.0;
fmt->mChannelsPerFrame = 1;
fmt->mBitsPerChannel = 32;
fmt->mBytesPerFrame = fmt->mChannelsPerFrame * sizeof (float);
fmt->mFramesPerPacket = 1;
fmt->mBytesPerPacket = fmt->mBytesPerFrame * fmt->mFramesPerPacket;
fmt->mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved;
OSStatus r = 0;
r = AudioQueueNewInput(&S.mDataFormat, HandleInputBuffer, &S, NULL, kCFRunLoopCommonModes, 0, &S.mQueue);
PRINT_R;
UInt32 dataFormatSize = sizeof (S.mDataFormat);
r = AudioQueueGetProperty (
S.mQueue,
kAudioConverterCurrentInputStreamDescription,
&S.mDataFormat,
&dataFormatSize
);
S.bufferByteSize = 22050;
for (int i = 0; i < NUM_BUFFERS; ++i) {
r = AudioQueueAllocateBuffer(S.mQueue, S.bufferByteSize, &S.mBuffers[i]);
PRINT_R;
r = AudioQueueEnqueueBuffer(S.mQueue, S.mBuffers[i], 0, NULL);
PRINT_R;
}
S.mCurrentPacket = 0;
S.mIsRunning = true;
r = AudioQueueStart(S.mQueue, NULL);
PRINT_R;
r = AudioQueueStop(S.mQueue, true);
S.mIsRunning = false;
PRINT_R;
r = AudioQueueDispose(S.mQueue, true);
}
Hier ist meine Eingangscallback-Funktion (in einer separaten C-Datei definiert):
void HandleInputBuffer (
void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc
) {
struct AQRecorderState *pAqData = (struct AQRecorderState *) aqData;
if (inNumPackets == 0 && pAqData->mDataFormat.mBytesPerPacket != 0) {
inNumPackets =
inBuffer->mAudioDataByteSize/pAqData->mDataFormat.mBytesPerPacket;
}
printf("%f\n", *(float*)inBuffer->mAudioData);
if (pAqData->mIsRunning == 0)
return;
AudioQueueEnqueueBuffer(pAqData->mQueue, inBuffer, 0, NULL);
}
Wenn das Programm ausgeführt wird, alle der Core Audio-Funktionsaufrufe 0 zurück, die (glaube ich) für „kein Fehler“, und HandleInputBuffer wird NUM_BUFFERS mal in sehr schneller Folge oder fast sofort genannt (die meisten definitiv nicht alle 0,5 Se cs wie die Puffergröße von 22050 würde bei dieser Abtastrate vorschlagen, und alle ersten Abtastwerte sind 0,0. Was fehlt mir hier?
Mein C wird verrostet. Müssen Sie nicht "Malloc" 'S' zuordnen? Auch die Formatwerte sehen für mich irgendwie willkürlich aus. Warum 32 Bit/Kanal? Warum diese formatFlags? – shallowThought
Ach ja, beim Aufruf von 'AudioQueueNewInput' mit ungültigen Werten im ASBD wird eine Fehlermeldung (" fmt? ") Ausgegeben, die die Standardwerte des Standard-Eingabegerätes enthält und von wo ich die Werte herbekomme. Ich glaube auch, 'AudioQueueAllocateBuffer' macht die Zuweisung – ehoopz
' AudioQueueNewInput' arbeitet mit 'fmt-> mBitsPerChannel = 16' und' fmt-> mFormatFlags = kAudioFormatFlagIsSignedInteger' aber immer noch keine Eingabe. Ich wundere mich irgendwie, warum es "io: 44100 Hz, 32-Bit Float" für das eingebaute Mikrofon sagt, obwohl – ehoopz