多次使用一个临时文件

时间:2014-12-12 18:49:26

标签: c# naudio

我正在使用SoundStrecher类来更改音频的压缩率。新音频正在写入另一个文件中。

    static void processWave(string fileIn, string fileOut, float newTempo = 1.4f, float newPitch = 1, float newRate = 1)
    {
        WaveFileReader reader = new WaveFileReader(fileIn);

        int numChannels = reader.WaveFormat.Channels, sampleRate = reader.WaveFormat.SampleRate;
        int bitPerSample = reader.WaveFormat.BitsPerSample;

        const int BUFFER_SIZE = 1024 * 16;

        SoundStretcher stretcher = new SoundStretcher(sampleRate, numChannels);
        WaveFileWriter writer = new WaveFileWriter(fileOut, new WaveFormat(sampleRate, 16, numChannels));

        stretcher.Tempo = newTempo;
        stretcher.Pitch = newPitch;
        stretcher.Rate = newRate;

        byte[] buffer = new byte[BUFFER_SIZE];
        short[] buffer2 = null;

        if (bitPerSample == 8)
            buffer2 = new short[BUFFER_SIZE];

        bool finished = false;

        while (true)
        {
            int bytesRead = 0;
            if (!finished)
            {
                bytesRead = reader.Read(buffer, 0, BUFFER_SIZE);

                if (bytesRead == 0)
                {
                    finished = true;
                    stretcher.Flush();
                }
                else
                {
                    if (bitPerSample == 16)
                        stretcher.PutSamplesFromBuffer(buffer, 0, bytesRead);

                    else if (bitPerSample == 8)
                    {
                        for (int i = 0; i < BUFFER_SIZE; i++)
                            buffer2[i] = (short)((buffer[i] - 128) * 256);
                        stretcher.PutSamples(buffer2);
                    }
                }
            }
            bytesRead = stretcher.ReceiveSamplesToBuffer(buffer, 0, BUFFER_SIZE);
            writer.WriteData(buffer, 0, bytesRead);

            if (finished && bytesRead == 0)
                break;
        }


        reader.Close();
        writer.Close();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        processWave("D:\\us1.wav","D:\\vs2.wav");
        WaveOut obj = new WaveOut();
        WaveFileReader h = new WaveFileReader("D:\\vs2.wav");
        obj.Init(h);
        obj.Play();
    }

我遇到这个例外:

An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file 'D:\vs2.wav' because it is being used by another process.

当我将表单加载事件更改为:

        for (int i = 1; i <= 2; i++)
        {
            processWave("D:\\us1.wav", "D:\\vs2.wav");
            WaveOut obj = new WaveOut();
            WaveFileReader h = new WaveFileReader("D:\\vs2.wav");
            obj.Init(h);
            obj.Play();
        }

我如何继续使用vs2.wav作为我的临时文件?

2 个答案:

答案 0 :(得分:0)

尝试使用using语句在processWave中包装编写器:

static void processWave(string fileIn, string fileOut, float newTempo = 1.4f, float newPitch = 1, float newRate = 1)
{
    using (WaveFileReader reader = new WaveFileReader(fileIn))
    {

        int numChannels = reader.WaveFormat.Channels, sampleRate = reader.WaveFormat.SampleRate;
        int bitPerSample = reader.WaveFormat.BitsPerSample;

        const int BUFFER_SIZE = 1024 * 16;

        SoundStretcher stretcher = new SoundStretcher(sampleRate, numChannels);

        using (WaveFileWriter writer = new WaveFileWriter(fileOut, new WaveFormat(sampleRate, 16, numChannels)))
        {

            stretcher.Tempo = newTempo;
            stretcher.Pitch = newPitch;
            stretcher.Rate = newRate;

            byte[] buffer = new byte[BUFFER_SIZE];
            short[] buffer2 = null;

            if (bitPerSample == 8)
                buffer2 = new short[BUFFER_SIZE];

            bool finished = false;

            while (true)
            {
                int bytesRead = 0;
                if (!finished)
                {
                    bytesRead = reader.Read(buffer, 0, BUFFER_SIZE);

                    if (bytesRead == 0)
                    {
                        finished = true;
                        stretcher.Flush();
                    }
                    else
                    {
                        if (bitPerSample == 16)
                            stretcher.PutSamplesFromBuffer(buffer, 0, bytesRead);

                        else if (bitPerSample == 8)
                        {
                            for (int i = 0; i < BUFFER_SIZE; i++)
                                buffer2[i] = (short)((buffer[i] - 128) * 256);
                            stretcher.PutSamples(buffer2);
                        }
                    }
                }
                bytesRead = stretcher.ReceiveSamplesToBuffer(buffer, 0, BUFFER_SIZE);
                writer.WriteData(buffer, 0, bytesRead);

                if (finished && bytesRead == 0)
                    break;
            }


            writer.Close();
        }

        reader.Close();
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 1; i <= 2; i++)
    {
        processWave("D:\\us1.wav", "D:\\vs2.wav");
        WaveOut obj = new WaveOut();

        using (WaveFileReader h = new WaveFileReader("D:\\vs2.wav"))
        {
            obj.Init(h);
            obj.Play();
        }
    }

    /*
    processWave("D:\\us1.wav","D:\\vs2.wav");
    WaveOut obj = new WaveOut();

    using (WaveFileReader h = new WaveFileReader("D:\\vs2.wav"))
    {
        obj.Init(h);
        obj.Play();
    }
    */
}

答案 1 :(得分:0)

我通过使用waveout的flipstopped事件解决了这个问题。错误发生了,因为在音频完成后,读者没有离开文件,即它仍处于阅读模式中打开...我所做的就是完成播放后关闭阅读器,从而将文件从阅读模式关闭

代码:

  WaveOut waveOut = new WaveOut();
  waveOut.PlaybackStopped += obj_PlaybackStopped;

并且在obj_PlaybackStopped事件中我关闭了我的wavefilereader:

  waveFileReader.Close();