4

InputAudioQueue を使用して iPhone 4s のマイクからサウンドを録音するために、MonoTouch で小さなプログラムを作成しました。

記録したデータを配列に保存し、このバッファをオーディオ プレーヤーにフィードして再生します (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);
    }
}
4

1 に答える 1

4

わかりました、これは手遅れかもしれませんが、ゴミの音だけが聞こえるという同じ問題があり、解決策を見つけました。

e.IntPtrBuffer からオーディオ データを直接読み取ることはできません。このポインターは AudioQueueBuffer オブジェクトへのポインターであり、オーディオ データ自体へのポインターではありません。したがって、オーディオ データを読み取るには、このオブジェクトへのアクセスを提供する e.UnsafeBuffer を使用し、その AudioData ポインターを使用できます。これは (安全でないコンテキストで) byte* または short* にキャストできる IntPtr であり、オーディオ データがあります。

よろしくお願いします

アレックス

于 2013-11-17T10:17:34.563 に答える