2012-09-22 46 views
5

我移植一些C#的Windows Phone 7個應用到Windows 8的打從生成的緩衝聲音在Windows 8應用

的手機應用程序使用XNA SoundEffect從緩衝播放任意聲音。在最簡單的情況下,我只是創建一個所需持續時間和頻率的正弦波。持續時間和頻率都會有很大的不同,所以我不想依賴MediaElements(除非有一些方法可以改變基本文件的頻率,但這隻會幫助我進行單頻生成)。

WinRT中的XNA SoundEffectInstance等效於什麼?

我認爲我需要爲此使用DirectX,但我不確定如何從其他C#/ XAML應用程序去解決此問題。我看過SharpDX,但它似乎沒有我認爲需要使用的DirectSound,SecondaryBuffer,SecondaryBuffer類。

我已經做了上面的一些假設。這可能是我正在尋找錯誤的類,或者有一種完全獨立的方式來從Windows 8應用程序生成任意聲音。


我發現an example using XAudio2 from SharpDX to play a wav file via an AudioBuffer。這似乎很有希望,我只需要將我生成的音頻緩衝區替換爲本地文件流。

PM>安裝,包裝SharpDX

PM>安裝,包裝SharpDX.XAudio2

public void PlaySound() 
    { 
     XAudio2 xaudio; 
     MasteringVoice masteringVoice; 

     xaudio = new XAudio2(); 
     masteringVoice = new MasteringVoice(xaudio); 

     var nativefilestream = new NativeFileStream(
      @"Assets\SpeechOn.wav", 
      NativeFileMode.Open, 
      NativeFileAccess.Read, 
      NativeFileShare.Read); 

     var soundstream = new SoundStream(nativefilestream); 


     var waveFormat = soundstream.Format; 
     var buffer = new AudioBuffer 
     { 
      Stream = soundstream.ToDataStream(), 
      AudioBytes = (int)soundstream.Length, 
      Flags = BufferFlags.EndOfStream 
     }; 

     var sourceVoice = new SourceVoice(xaudio, waveFormat, true); 

     // There is also support for shifting the frequency. 
     sourceVoice.SetFrequencyRatio(0.5f); 

     sourceVoice.SubmitSourceBuffer(buffer, soundstream.DecodedPacketsInfo); 

     sourceVoice.Start(); 
    } 
+0

我要尋找一個解決方案,我應該能夠從緩衝的音頻數據包的Windows Phone 8直接播放音頻?你可以重定向到一個工作的例子。 – sunder

回答

8

在Win8RT生成動態聲音的唯一方法就是使用XAudio2,所以你應該能夠用SharpDX.XAudio2做到這一點。

而不是使用NativeFileStream的,只是實例化數據流直接給你管理的緩衝區(或者你可以使用非託管的緩衝區或讓的數據流中實例化一個給你)。該代碼會是這樣:

// Initialization phase, keep this buffer during the life of your application 
// Allocate 10s at 44.1Khz of stereo 16bit signals 
var myBufferOfSamples = new short[44100 * 10 * 2]; 

// Create a DataStream with pinned managed buffer 
var dataStream = DataStream.Create(myBufferOfSamples, true, true); 

var buffer = new AudioBuffer 
     { 
      Stream = dataStream, 
      AudioBytes = (int)dataStream.Length, 
      Flags = BufferFlags.EndOfStream 
     }; 

//... 
// Fill myBufferOfSamples 
//... 

// PCM 44.1Khz stereo 16 bit format 
var waveFormat = new WaveFormat(); 

XAudio2 xaudio = new XAudio2(); 
MasteringVoice masteringVoice = new MasteringVoice(xaudio); 
var sourceVoice = new SourceVoice(xaudio, waveFormat, true); 

// Submit the buffer 
sourceVoice.SubmitSourceBuffer(buffer, null); 

// Start playing 
sourceVoice.Start(); 

的抽樣方法與正弦波填充緩衝區:

private void FillBuffer(short[] buffer, int sampleRate, double frequency) 
    { 
     double totalTime = 0; 

     for (int i = 0; i < buffer.Length - 1; i += 2) 
     { 
      double time = (double)totalTime/(double)sampleRate; 
      short currentSample = (short)(Math.Sin(2 * Math.PI * frequency * time) * (double)short.MaxValue); 

      buffer[i] = currentSample; //(short)(currentSample & 0xFF); 
      buffer[i + 1] = currentSample; //(short)(currentSample >> 8); 

      totalTime += 2; 
     } 

    } 
+0

太好了,謝謝。我已經通過創建XAudio2實例擴展了您的示例。我現在從緩衝區生成一個聲音。目前似乎有點扭曲。我需要仔細檢查我的FillBuffer方法,這也是我加入到你的答案供他人使用。使用時,我在XNA正在來填充字節[] –

+0

我FillBuffer方法。卸下按位與和右移>>運營商解決了這個問題。我現在得到了一個清晰的音調。 –

+0

這有一個錯誤:'totalTime + = 2'意味着它產生兩倍的頻率。它應該是'totalTime ++'。 (自己測試過!) –

相關問題