2011-02-14 57 views
0

我正在使用DirectSound將正弦波寫入音頻卡。樣本大小爲16位,一個通道。我的問題是,要製作五秒鐘的聲音需要多少個樣本?採樣率是每秒44100個採樣。數學很簡單:220500就是答案。但是,這讓我瘋狂,因爲我的代碼只能玩大約一半的時間!這是我的代碼:DirectSound計時和採樣計數

using Microsoft.DirectX.DirectSound; 
using System; 
namespace Audio 
{ 
    // The class 
    public class Oscillator 
    { 
     static void Main(string[] args) 
     { 

      // Set up wave format 
      WaveFormat waveFormat = new WaveFormat(); 
      waveFormat.FormatTag = WaveFormatTag.Pcm; 
      waveFormat.Channels = 1; 
      waveFormat.BitsPerSample = 16; 
      waveFormat.SamplesPerSecond = 44100; 
      waveFormat.BlockAlign = (short)(waveFormat.Channels * waveFormat.BitsPerSample/8); 
      waveFormat.AverageBytesPerSecond = waveFormat.BlockAlign * waveFormat.SamplesPerSecond; 

      // Set up buffer description 
      BufferDescription bufferDesc = new BufferDescription(waveFormat); 
      bufferDesc.Control3D = false; 
      bufferDesc.ControlEffects = false; 
      bufferDesc.ControlFrequency = true; 
      bufferDesc.ControlPan = true; 
      bufferDesc.ControlVolume = true; 
      bufferDesc.DeferLocation = true; 
      bufferDesc.GlobalFocus = true; 

      Device d = new Device(); 
      d.SetCooperativeLevel(new System.Windows.Forms.Control(), CooperativeLevel.Priority); 


      int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels; 
      char[] buffer = new char[samples]; 

      // Set buffer length 
      bufferDesc.BufferBytes = buffer.Length * waveFormat.BlockAlign; 

      // Set initial amplitude and frequency 
      double frequency = 500; 
      double amplitude = short.MaxValue/3; 
      double two_pi = 2 * Math.PI; 
      // Iterate through time 
      for (int i = 0; i < buffer.Length; i++) 
      { 
       // Add to sine 
       buffer[i] = (char)(amplitude * 
        Math.Sin(i * two_pi * frequency/waveFormat.SamplesPerSecond)); 
      } 

      SecondaryBuffer bufferSound = new SecondaryBuffer(bufferDesc, d); 
      bufferSound.Volume = (int)Volume.Max; 
      bufferSound.Write(0, buffer, LockFlag.None); 
      bufferSound.Play(0, BufferPlayFlags.Default); 
      System.Threading.Thread.Sleep(10000); 
     } 
    } 
} 

通過我的計算,這應該發揮5秒。它打了半場。如果我改變

int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels; 

int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels 
     * waveFormat.BlockAlign; 

接着將聲卡工作正常的,但是這是一個黑客,對不對?當然,我做錯了什麼,但我不知道是什麼。

謝謝你的時間。

回答

0

如果我沒有弄錯,每個樣本對於16位都會有2個字節,因此您的緩衝區字節數將是樣本計數的兩倍。

+0

「你將有2個樣本咬」這就是爲什麼我使用`char`而不是`byte`。每個'char'是2個字節,對吧?看起來我應該使用`ushort`並避免混淆! – 2012-12-31 17:30:33