I wrote a small program in MonoTouch to record the sound from the microphone of my iPhone 4 using InputAudioQueue.
I save the recorded data in an array and feed this buffer to my audio player for playback (using OutputAudioQueue).
When playing just a little stuttering garbage / static sound. I tried to fill the buffer with sin waves before playing, and then it sounds good, so I think the problem is in the recording, not in the playback. Can someone help me figure out what is wrong? (Code below)
public class AQRecorder { private const int CountAudioBuffers = 3; private const int AudioBufferLength = 22050; private const int SampleRate = 44100; private const int BitsPerChannel = 16; private const int Channels = 1; private const int MaxRecordingTime = 5; private AudioStreamBasicDescription audioStreamDescription; private InputAudioQueue inputQueue; private short[] rawData; private int indexNextRawData; public AQRecorder () { this.audioStreamDescription.Format = AudioFormatType.LinearPCM; this.audioStreamDescription.FormatFlags = AudioFormatFlags.LinearPCMIsSignedInteger | AudioFormatFlags.LinearPCMIsPacked; this.audioStreamDescription.SampleRate = AQRecorder.SampleRate; this.audioStreamDescription.BitsPerChannel = AQRecorder.BitsPerChannel; this.audioStreamDescription.ChannelsPerFrame = AQRecorder.Channels; this.audioStreamDescription.BytesPerFrame = (AQRecorder.BitsPerChannel / 8) * AQRecorder.Channels; this.audioStreamDescription.FramesPerPacket = 1; this.audioStreamDescription.BytesPerPacket = audioStreamDescription.BytesPerFrame * audioStreamDescription.FramesPerPacket; this.audioStreamDescription.Reserved = 0; } public void Start () { int totalBytesToRecord = this.audioStreamDescription.BytesPerFrame * AQRecorder.SampleRate * AQRecorder.MaxRecordingTime; this.rawData = new short[totalBytesToRecord / sizeof(short)]; this.indexNextRawData = 0; this.inputQueue = SetupInputQueue (this.audioStreamDescription); this.inputQueue.Start (); } public void Stop () { if (this.inputQueue.IsRunning) { this.inputQueue.Stop (true); } } public short[] GetData () { return this.rawData;; } private InputAudioQueue SetupInputQueue (AudioStreamBasicDescription audioStreamDescription) { InputAudioQueue inputQueue = new InputAudioQueue (audioStreamDescription); for (int count = 0; count < AQRecorder.CountAudioBuffers; count++) { IntPtr bufferPointer; inputQueue.AllocateBuffer(AQRecorder.AudioBufferLength, out bufferPointer); inputQueue.EnqueueBuffer(bufferPointer, AQRecorder.AudioBufferLength, null); } inputQueue.InputCompleted += HandleInputCompleted; return inputQueue; } private void HandleInputCompleted (object sender, InputCompletedEventArgs e) { unsafe { short* shortPtr = (short*)e.IntPtrBuffer; for (int count = 0; count < AQRecorder.AudioBufferLength; count += sizeof(short)) { if (indexNextRawData >= this.rawData.Length) { this.inputQueue.Stop (true); return; } this.rawData [indexNextRawData] = *shortPtr; indexNextRawData++; shortPtr++; } } this.inputQueue.EnqueueBuffer(e.IntPtrBuffer, AQRecorder.AudioBufferLength, null); } }
source share