首页 > 解决方案 > Xamarin.Android 和 RecordAudio:如何结合文件写入和其他任务

问题描述

我开发了一个Xamarin.Android 应用程序,我需要在 .wav 中录制音频文件并同时显示相关的频谱图

我能够分别执行这2 个任务,但不能将它们组合起来。

我使用 anAudioRecord通过麦克风录制声音:

public async Task StartRecording()
{   
    audioRecord = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, bufferSize);
    if (audioRecord.State == State.Initialized)
        audioRecord.StartRecording();
    isRecording = true;
    recordingThread = new System.Threading.Thread(new ThreadStart(
        WriteAudioDataToFile
        ));
    recordingThread.Start();
}

文件写入已完成WriteAudioDataToFile()并且工作正常:

private void WriteAudioDataToFile()
{
    byte[] data = new byte[bufferSize];
    string filename = GetTempFilename();
    FileOutputStream fos = null;
    try
    {
        fos = new FileOutputStream(filename);
    }
    catch (Java.IO.FileNotFoundException e)
    {
    }
    int read = 0;

    if (null != fos)
    {
        while (isRecording)
        {
            read = audioRecord.Read(data, 0, bufferSize);
            if ((int)RecordStatus.ErrorInvalidOperation != read)
            {
                try
                {
                    fos.Write(data);                                                            
                }
                catch (Java.IO.IOException e)
                {
                }
            }
        }
        try
        {
            fos.Close();
        }
        catch (Java.IO.IOException e)
        {
        }
    }
}

我想在文件写入后执行其他任务:

void OnNext()
{
    short[] audioBuffer = new short[2048];
    audioRecord.Read(audioBuffer, 0, audioBuffer.Length);
    int[] result = new int[audioBuffer.Length];
    for (int i = 0; i < audioBuffer.Length; i++)
    {
        result[i] = (int)audioBuffer[i];
    }
    samplesUpdated(this, new SamplesUpdatedEventArgs(result));
}

如果我OnNext()从调用StartRecording(),而不编写文件,这可以正常工作,并且我得到了频谱图的预期值:

public async Task StartRecording()
{   
    audioRecord = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, bufferSize);
    if (audioRecord.State == State.Initialized)
        audioRecord.StartRecording();
    isRecording = true;
    while (audioRecord.RecordingState == RecordState.Recording)
    {
        OnNext();
    }
}

但由于我需要结合文件写入和其他任务,我尝试在文件写入后移动OnNext()方法:

private void WriteAudioDataToFile()
{
    //...
    try
    {
        fos.Write(data);                                        

        short[] dataShort = new short[bufferSize];
        dataShort = Array.ConvertAll(data, d => (short)d);
        int[] result = new int[dataShort.Length];
        for (int i = 0; i < dataShort.Length; i++)
        {
            result[i] = (int)dataShort[i];
        }                   
        samplesUpdated(this, new SamplesUpdatedEventArgs(result));
    }
    catch (Java.IO.IOException e)
    {
    }
    //...
}

但这根本不像预期的那样工作:

我不明白如何管理audioRecord.Read(data, 0, bufferSize)

=> 实现这一目标的更好方法应该是什么?

编辑:

我已经尝试过这些方法,但这并没有改变任何东西:

我还查看了 AudioRecord 停止后是否可以写入文件,但似乎也不可能......

标签: c#arraysxamarin.androidstreamwriteraudiorecord

解决方案


推荐阅读