2011-08-22 46 views
3

所以我所用的是一個表示WAV文件原始數據的short []數組。這意味着它不包含通常包含的任何頁眉或頁腳信息。爲了播放這個音頻,我需要將它轉換爲某種類型的流,不幸的是,這個short []數組中的數據是Int16,其中很多值超過了255,因此無法轉換爲字節並且無法轉換爲流。有沒有人有任何想法我將如何能夠播放此音頻數據?將short []轉換爲可以作爲音頻播放的流

+0

「某種形式的流」過於模糊;如果你知道所需的佈局,字節順序等 - 即輸入=>輸出... –

回答

9

可以短數組轉換回一個字節數組:

short[] sampleData = ... 
byte[] byteArray = new byte[sampleData.Length*2]; 
Buffer.BlockCopy(sampleData , 0, byteArray, 0, byteArray.Length); 

然後你就可以使用下面的WaveMemoryStream類創建一波流 - 爲你需要知道你的樣本數據的波形格式。然後該流可以保存爲WAV文件或由SoundPlayer播放。

public class WaveMemoryStream : Stream 
{ 
    public override bool CanSeek { get { return false; } } 
    public override bool CanWrite { get { return false; } } 
    public override bool CanRead { get { return true; } } 
    public override long Length { get { return _waveStream.Length; } } 
    public override long Position { get { return _waveStream.Position; } set { _waveStream.Position = value; } } 

    private MemoryStream _waveStream; 

    public WaveMemoryStream(byte[] sampleData, int audioSampleRate, ushort audioBitsPerSample, ushort audioChannels) 
    { 
     _waveStream = new MemoryStream(); 
     WriteHeader(_waveStream, sampleData.Length, audioSampleRate, audioBitsPerSample, audioChannels); 
     WriteSamples(_waveStream, sampleData); 
     _waveStream.Position = 0; 
    } 

    public void WriteHeader(Stream stream, int length, int audioSampleRate, ushort audioBitsPerSample, ushort audioChannels) 
    { 
     BinaryWriter bw = new BinaryWriter(stream); 

     bw.Write(new char[4] { 'R', 'I', 'F', 'F' }); 
     int fileSize = 36 + length; 
     bw.Write(fileSize); 
     bw.Write(new char[8] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' }); 
     bw.Write((int)16); 
     bw.Write((short)1); 
     bw.Write((short)audioChannels); 
     bw.Write(audioSampleRate); 
     bw.Write((int)(audioSampleRate * ((audioBitsPerSample * audioChannels)/8))); 
     bw.Write((short)((audioBitsPerSample * audioChannels)/8)); 
     bw.Write((short)audioBitsPerSample); 

     bw.Write(new char[4] { 'd', 'a', 't', 'a' }); 
     bw.Write(length); 
    } 

    public void WriteSamples(Stream stream, byte[] sampleData) 
    { 
     BinaryWriter bw = new BinaryWriter(stream); 
     bw.Write(sampleData, 0, sampleData.Length); 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     return _waveStream.Read(buffer, offset, count); 
    } 

    public virtual void WriteTo(Stream stream) 
    { 
     int bytesRead = 0; 
     byte[] buffer = new byte[8192]; 

     do 
     { 
      bytesRead = Read(buffer, 0, buffer.Length); 
      stream.Write(buffer, 0, bytesRead); 
     } while (bytesRead > 0); 

     stream.Flush(); 
    } 

    public override void Flush() 
    { 
     _waveStream.Flush(); 
    } 

    public override long Seek(long offset, SeekOrigin origin) 
    { 
     return _waveStream.Seek(offset, origin); 
    } 

    public override void SetLength(long value) 
    { 
     throw new NotImplementedException(); 
    } 
    public override void Write(byte[] buffer, int offset, int count) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

謝謝...這對我有很大的幫助。 – UNOWN301