DirectSound Timing и подсчет образцов - PullRequest
0 голосов
/ 15 февраля 2011

Я использую DirectSound для записи синусоидальной волны на звуковую карту.Размер выборки 16 бит, один канал.У меня вопрос, сколько сэмплов нужно сделать, чтобы сделать пятисекундный звук?Частота дискретизации составляет 44100 выборок в секунду.Математика проста: 220500 является ответом.Это сводит меня с ума, потому что мой код воспроизводит только примерно половину этого времени !!Вот мой код:

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;

Тогда звук работает нормально, но это взлом, верно?Конечно, я делаю что-то не так, но я не могу сказать, что.

Спасибо за ваше время.

1 Ответ

0 голосов
/ 17 декабря 2011

Если я не ошибаюсь, у вас будет 2 байта на 16-битную выборку, поэтому количество байтов в буферах будет вдвое больше, чем количество выборок.

...