2014-06-09 5 views
2

먼저 무엇인가 잘못 되었으면 용서해주세요.이 플랫폼에서 새로운 것입니다. 여기에는 원하는 사람들을위한 음성 녹음기의 좋은 예제가 있습니다. Windows phone 8에서 오디오 레코더 기능을 만들었으므로 모든 것이 잘 작동하지만 시간의 의미로 오디오 확장, 오디오 이름 및 오디오 길이를 얻으려면 어떻게해야합니까?Windows Phone 8의 오디오 레코더 문제

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; 
    } 

답변

3

내가 온라인 예제를 따라 난 당신의 코드에서 누락 된 일도가 발견 : 자세한 내용은 내 코드를 참조하십시오.

이러한 두 가지 방법이 있어야합니다

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); 
    } 

그런 다음 당신이 microphone.Stop() 호출 후 stopButton_ClickrecordButton_Click 방법에 WriteWavHeaderUpdateWavHeader를 호출해야합니다.

마이크가 PCM 데이터를 반환하기 때문에 이러한 헤더의 작업은 스트림을 wav 파일로 변환 한 다음 나중에 Isolated Storage에 저장할 수 있습니다. 어떻게 시간의 의미에서 파일 길이를받을 수 있나요 어디 위의 코드 내 파일 이름입니다,

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(); 
    } 
+0

안드레 thnx, 당신이 나에게 한 대답을 줄 수 아래

는 IsolatedStorage에 파일을 저장하는 코드입니다 너 형제 고마워 !! –

+1

나는 답을 편집하고 te 파일을 isolatedStorage에 저장하는 코드를 추가했습니다. 파일에 원하는 이름을 지정할 수 있습니다. 파일의 지속 시간을 찾으려면 Stop 핸들러에서 다음 메소드를 호출 할 수 있습니다. 'microphone.GetSampleDuration ((int) stream.Length); ' long을 기대하면 int.MaxValue보다 크지 않습니다. 그렇지 않으면 나중에 IsolatedStorage에서 MediaElement로 파일을로드 할 수 있으며 원하는 기간에 길이가 표시됩니다. 대답이 맞다면 올바른 것으로 표시하십시오.) 감사합니다. – Meneses

+0

Andre, 감사합니다. 사용자 문자열 filename = "demo.wav"를 사용할 수 있습니까? 정말 고마워요. –