首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DirectSound时序和采样计数

DirectSound时序和采样计数
EN

Stack Overflow用户
提问于 2011-02-15 05:16:23
回答 1查看 3.1K关注 0票数 0

我正在使用DirectSound向音频卡写入一个正弦波。采样大小为16位,单通道。我的问题是,需要多少样本才能发出5秒的声音?采样率为每秒44100个样本。数学很简单: 220500是答案。然而,这让我抓狂,因为我的代码只运行了大约一半的时间!下面是我的代码:

代码语言:javascript
复制
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秒。它在中场休息时播放。如果我改变了

代码语言:javascript
复制
 int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels;

代码语言:javascript
复制
  int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels
      * waveFormat.BlockAlign;

然后声音工作正常,但这是一个黑客,不是吗?我肯定做错了什么,但我不知道是什么。

耽误您时间,实在对不起。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-17 19:29:52

如果我没记错的话,对于16位的每个样本,你将有2个字节,因此你的缓冲区字节计数将是样本计数的两倍。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4997360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档