C# Windows Phone 8中的录音机问题

C# Windows Phone 8中的录音机问题,c#,windows-phone-8,C#,Windows Phone 8,首先,如果做错了什么,那么请原谅我,我是这个平台的新手。 这里是一个很好的和工作的声音录音机的例子,为那些谁想要。 我已经在WindowsPhone8中创建了录音功能,一切都很好,但如何获得音频扩展、音频名称和音频长度? 有关更多详细信息,请参阅我的代码: private Microphone microphone = Microphone.Default; private byte[] buffer; priv

首先,如果做错了什么,那么请原谅我,我是这个平台的新手。 这里是一个很好的和工作的声音录音机的例子,为那些谁想要。 我已经在WindowsPhone8中创建了录音功能,一切都很好,但如何获得音频扩展、音频名称和音频长度? 有关更多详细信息,请参阅我的代码:

private Microphone microphone = Microphone.Default;
    private byte[] buffer;                                  
    private MemoryStream stream = new MemoryStream();       
    private SoundEffectInstance soundInstance;              
    private bool soundIsPlaying = false;

    private BitmapImage blankImage;
    private BitmapImage microphoneImage;
    private BitmapImage speakerImage;

 public App()
    {
        InitializeComponent();

        DispatcherTimer dt = new DispatcherTimer();
        dt.Interval = TimeSpan.FromMilliseconds(33);
        dt.Tick += dt_Tick;
        dt.Start();

        microphone.BufferReady += microphone_BufferReady;

        blankImage = new BitmapImage(new Uri("Img/blank.png", UriKind.RelativeOrAbsolute));
        microphoneImage = new BitmapImage(new Uri("Img/microphone.png", UriKind.RelativeOrAbsolute));
        speakerImage = new BitmapImage(new Uri("Img/speaker.png", UriKind.RelativeOrAbsolute));      
    }

 void dt_Tick(object sender, EventArgs e)
    {
        try { FrameworkDispatcher.Update(); }
        catch { }

        if (true == soundIsPlaying)
        {
            if (soundInstance.State != SoundState.Playing)
            {
                // Audio has finished playing
                soundIsPlaying = false;

                // Update the UI to reflect that the 
                // sound has stopped playing
                SetButtonStates(true, true, false);
                UserHelp.Text = "press play\nor record";
                StatusImage.Source = blankImage;
            }
        }
    }

 void microphone_BufferReady(object sender, EventArgs e)
    {
        microphone.GetData(buffer);

        stream.Write(buffer, 0, buffer.Length);

    }

 private void recordButton_Click(object sender, EventArgs e)
    {
        microphone.BufferDuration = TimeSpan.FromMilliseconds(500);


        buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];

        string audiofile = Convert.ToBase64String(buffer);
        string audiosize = stream.Length.ToString();

        stream.SetLength(0);

        microphone.Start();

        SetButtonStates(false, false, true);
        UserHelp.Text = "record";
        StatusImage.Source = microphoneImage;
        btnAdd.Visibility = Visibility.Collapsed;
    }

 private void playButton_Click(object sender, EventArgs e)
    {
        if (stream.Length > 0)
        {
            // Update the UI to reflect that
            // sound is playing
            SetButtonStates(false, false, true);
            UserHelp.Text = "play";
            StatusImage.Source = speakerImage;

            // Play the audio in a new thread so the UI can update.
            Thread soundThread = new Thread(new ThreadStart(playSound));
            soundThread.Start();
            btnAdd.Visibility = Visibility.Visible;
        }

    }

 private void stopButton_Click(object sender, EventArgs e)
    {
        if (microphone.State == MicrophoneState.Started)
        {
            // In RECORD mode, user clicked the 
            // stop button to end recording
            microphone.Stop();
        }
        else if (soundInstance.State == SoundState.Playing)
        {
            // In PLAY mode, user clicked the 
            // stop button to end playing back
            soundInstance.Stop();
        }

        SetButtonStates(true, true, false);
        UserHelp.Text = "ready";
        StatusImage.Source = blankImage;

        btnAdd.Visibility = Visibility.Visible;
    }

    private void playSound()
    {

        SoundEffect sound = new SoundEffect(stream.ToArray(), microphone.SampleRate, AudioChannels.Mono);
        soundInstance = sound.CreateInstance();
        soundIsPlaying = true;
        soundInstance.Play();
    }

private void SetButtonStates(bool recordEnabled, bool playEnabled, bool stopEnabled)
    {
        (ApplicationBar.Buttons[0] as ApplicationBarIconButton).IsEnabled = recordEnabled;
        (ApplicationBar.Buttons[1] as ApplicationBarIconButton).IsEnabled = playEnabled;
        (ApplicationBar.Buttons[2] as ApplicationBarIconButton).IsEnabled = stopEnabled;
    }

我在网上遵循了一个示例,我注意到您的代码中缺少了一些东西

您还应该有以下两种方法:

    public void WriteWavHeader(int sampleRate)
    {
        const int bitsPerSample = 16;
        const int bytesPerSample = bitsPerSample / 8;
        var encoding = System.Text.Encoding.UTF8;

        // ChunkID Contains the letters "RIFF" in ASCII form (0x52494646 big-endian form).
        stream.Write(encoding.GetBytes("RIFF"), 0, 4);

        // NOTE this will be filled in later
        stream.Write(BitConverter.GetBytes(0), 0, 4);

        // Format Contains the letters "WAVE"(0x57415645 big-endian form).
        stream.Write(encoding.GetBytes("WAVE"), 0, 4);

        // Subchunk1ID Contains the letters "fmt " (0x666d7420 big-endian form).
        stream.Write(encoding.GetBytes("fmt "), 0, 4);

        // Subchunk1Size 16 for PCM. This is the size of therest of the Subchunk which follows this number.
        stream.Write(BitConverter.GetBytes(16), 0, 4);

        // AudioFormat PCM = 1 (i.e. Linear quantization) Values other than 1 indicate some form of compression.
        stream.Write(BitConverter.GetBytes((short)1), 0, 2);

        // NumChannels Mono = 1, Stereo = 2, etc.
        stream.Write(BitConverter.GetBytes((short)1), 0, 2);

        // SampleRate 8000, 44100, etc.
        stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);

        // ByteRate = SampleRate * NumChannels * BitsPerSample/8
        stream.Write(BitConverter.GetBytes(sampleRate * bytesPerSample), 0, 4);

        // BlockAlign NumChannels * BitsPerSample/8 The number of bytes for one sample including all channels.
        stream.Write(BitConverter.GetBytes((short)(bytesPerSample)), 0, 2);

        // BitsPerSample 8 bits = 8, 16 bits = 16, etc.
        stream.Write(BitConverter.GetBytes((short)(bitsPerSample)), 0, 2);

        // Subchunk2ID Contains the letters "data" (0x64617461 big-endian form).
        stream.Write(encoding.GetBytes("data"), 0, 4);

        // NOTE to be filled in later
        stream.Write(BitConverter.GetBytes(0), 0, 4);
    }


    public void UpdateWavHeader()
    {
        if (!stream.CanSeek) throw new Exception("Can't seek stream to update wav header");

        var oldPos = stream.Position;

        // ChunkSize 36 + SubChunk2Size
        stream.Seek(4, SeekOrigin.Begin);
        stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);

        // Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data.
        stream.Seek(40, SeekOrigin.Begin);
        stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);

        stream.Seek(oldPos, SeekOrigin.Begin);
    }
然后,您应该在
录制按钮上调用
WriteWavHeader
,然后在
停止按钮上调用
UpdateWavHeader
,在
麦克风.Stop()调用之后单击
麦克风.Stop()

因为麦克风返回PCM数据,所以这些头文件的作用是将数据流转换为wav文件,例如,您可以稍后将其保存在独立的存储器中

以下是将文件保存到IsolatedStorage的代码:

    private void SaveToIsolatedStorage(string filename)
    {
        // first, we grab the current apps isolated storage handle
        IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

        // we give our file a filename
        string strSaveName = filename;

        // if that file exists... 
        if (isf.FileExists(strSaveName))
        {
            // then delete it
            isf.DeleteFile(strSaveName);
        }

        // now we set up an isolated storage stream to point to store our data
        var isfStream = new IsolatedStorageFileStream(strSaveName, FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication());

        isfStream.Write(stream.ToArray(), 0, stream.ToArray().Length);

        // ok, done with isolated storage... so close it
        isfStream.Close();
    }

thnx Andre,你能给我一个答案吗,我如何获得时间意义上的文件长度,以及我的文件名在上面代码中的位置??谢谢兄弟!!我编辑了答案并添加了将te文件保存到isolatedStorage的代码。您可以为文件指定任何名称。要查找文件的持续时间,可以在停止处理程序中调用以下方法:
microscope.GetSampleDuration((int)stream.Length)希望您的long值不大于int.MaxValue。否则,您可以稍后从IsolatedStorage加载该文件作为MediaElement,并在那里看到所需的持续时间。如果答案正确,请标记为正确;)谢谢你,安德烈,谢谢你!我可以使用string filename=“demo.wav”吗?非常感谢。是的,这是正确的。该文件是wav格式的,因此您应该像以前一样使用.wav扩展名。否则你会没事的很高兴我能帮上忙。我从来没有必要将流转换成Base64字符串,但这确实会产生一些大问题:关于名称,您可以使用
string filename=Guid.NewGuid()+“.wav”