使用 AudioQueue 和 Monotouch 静态声音录制
Posted
技术标签:
【中文标题】使用 AudioQueue 和 Monotouch 静态声音录制【英文标题】:Recording with AudioQueue and Monotouch static sound 【发布时间】:2012-10-21 21:38:11 【问题描述】:我在 MonoTouch 中编写了一个小程序,使用 InputAudioQueue 从我的 iPhone 4s 的麦克风录制声音。
我将录制的数据保存在一个数组中,并将这个缓冲区提供给我的音频播放器进行播放(使用 OutputAudioQueue)。
播放时只是一些断断续续的垃圾/静态声音。我曾尝试在播放前用正弦波填充缓冲区,然后听起来不错,所以我猜问题出在录音中,而不是播放。谁能帮我看看有什么问题? (代码如下)
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);
【问题讨论】:
这是一个类似的代码示例,可能对您有所帮助:github.com/xamarin/monotouch-samples/tree/master/…. 感谢您的回答,但我在使用 AudioQueue 从麦克风而不是文件获取输入时遇到问题 :-) 【参考方案1】:好的,这可能为时已晚,但我也遇到了同样的问题,只听到垃圾声音并找到了解决方案。
您不能直接从 e.IntPtrBuffer 读取音频数据。此指针是指向 AudioQueueBuffer 对象的指针,而不是指向音频数据本身的指针。因此,要读取音频数据,您可以使用 e.UnsafeBuffer 来访问该对象并使用其 AudioData 指针。这是一个 IntPtr,您可以将其(在不安全的上下文中)转换为 byte* 或 short* 并且您拥有音频数据。
最好的问候
亚历克斯
【讨论】:
感谢您的回答 :-) 如果它解决了您的问题,您可以将我的回答标记为您问题的解决方案:)。 @BårdM 和 Alex,你们中的任何一个能否提供对我的 related question 的见解?以上是关于使用 AudioQueue 和 Monotouch 静态声音录制的主要内容,如果未能解决你的问题,请参考以下文章