在c#中 wave API播放.wav文件时控制播放音量

baihe_591 2008-06-24 11:06:26
要做多声卡项目,先从基本的多声卡控制wav文件做起,奇怪的是用waveOutGetVolume和waveOutSetVolume 来控制播放音量的时候发现,这两个函数控制的是输出设备的音量,即:我在自己的应用程序中控制音量时其他的所有播放器都受到控制,那怎样才能调节播放文件的音量,而不是控制输出设备的音量?


另外,有谁知道waveOutGetPosition函数怎么使用吗?和其中MMTime结构的定义吗?
...全文
783 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
li_527 2010-12-02
  • 打赏
  • 举报
回复
指导指导
qingcheng116 2010-04-05
  • 打赏
  • 举报
回复
迟来的Mark,顶!
GhostAdai 2008-06-25
  • 打赏
  • 举报
回复
这个Mark~
hanjun1024 2008-06-25
  • 打赏
  • 举报
回复
数据已经读入内存,代码都是直接操作内存里的值。从代码来看,应该是按比例修改声音数据的大小。声音数据也是按帧存放的,所以统一改变每帧数据的大就能控制波形的幅度。
baihe_591 2008-06-25
  • 打赏
  • 举报
回复
哈哈,问题解决了,参考的codeproject,只是不知道是什么原理,贴出来大家分析分析,

public void Process(byte[] buffer, int offset, int count)
{
BinaryReader From = new BinaryReader(new MemoryStream(buffer, offset, count));
BinaryWriter To = new BinaryWriter(new MemoryStream(buffer, offset, count));

int Samples = count / m_Format.nBlockAlign;

lock (this)
{
switch (m_Format.wBitsPerSample)
{
case 8:
if (m_Format.nChannels == 1) // mono
{
for (int i = 0; i < Samples; i++)
{
float x = (From.ReadByte() - 128.0f) / 128.0f;
float y = ProcessMono(x);
To.Write(ToByte(y));
}
}
else // stereo
{
for (int i = 0; i < Samples; i++)
{
float xyl = (From.ReadByte() - 128.0f) / 128.0f;
float xyr = (From.ReadByte() - 128.0f) / 128.0f;
ProcessStereo(ref xyl, ref xyr);
To.Write(ToByte(xyl));
To.Write(ToByte(xyr));
}
}
break;
case 16:
if (m_Format.nChannels == 1) // mono
{
for (int i = 0; i < Samples; i++)
{
float x = From.ReadInt16() / 32768.0f;
float y = ProcessMono(x);
To.Write(ToShort(y));
}
}
else // stereo
{
for (int i = 0; i < Samples; i++)
{
float xyl = From.ReadInt16() / 32768.0f;
float xyr = From.ReadInt16() / 32768.0f;
ProcessStereo(ref xyl, ref xyr);
To.Write(ToShort(xyl));
To.Write(ToShort(xyr));
}
}
break;
}
}
}
private byte ToByte(float x)
{
x = x * 128.0f + 128.0f;
return x > byte.MaxValue ? byte.MaxValue : x < byte.MinValue ? byte.MinValue : (byte)x;
}
private short ToShort(float x)
{
x = x * 32768.0f;
return x > short.MaxValue ? short.MaxValue : x < short.MinValue ? short.MinValue : (short)x;
}
private float m_Volume = 1.0f;
public float Volume
{
get { return m_Volume; }
set
{
lock (this)
m_Volume = value;
}
}

public bool Connect(WaveFormat format)
{
return true;
}
protected float ProcessMono(float x)
{
return x * m_Volume;
}
protected void ProcessStereo(ref float left, ref float right)
{
left = left * m_Volume;
right = right * m_Volume;
}



private void Filler(IntPtr data, int size)
{
byte[] b = new byte[size];

if (m_AudioStream!= null)
{
int pos = 0;
while (pos < size)
{
int toget = size - pos;
int got = m_AudioStream.Read(b, pos, toget);
if (got < toget)
// m_AudioStream.Position = 0; // loop if the file ends
{
playState = PlayState.Stopped;
return;

}
pos += got;
}
Process(b, 0, b.Length);
}
else
{
for (int i = 0; i < b.Length; i++)
b[i] = 0;
}
System.Runtime.InteropServices.Marshal.Copy(b, 0, data, size);
}



Process(b, 0, b.Length);这是为什么啊,难道要向缓冲写数据?这样不会改变文件?
viena 2008-06-25
  • 打赏
  • 举报
回复
不懂,帮顶~
yagebu1983 2008-06-25
  • 打赏
  • 举报
回复
学习一楼的!!!
帮你顶!!
yeak2001 2008-06-25
  • 打赏
  • 举报
回复
过来学习,没有搞过这个,高科技啊
baihe_591 2008-06-25
  • 打赏
  • 举报
回复
看来得发一个通缉令了.
jinjazz,amandag,zswang,zhoufoxcn ,viena,还有我还没有认识的、深藏不漏的快快现身!
kbryant 2008-06-25
  • 打赏
  • 举报
回复
学习以下
Adechen 2008-06-25
  • 打赏
  • 举报
回复
学习

mark一下
baihe_591 2008-06-25
  • 打赏
  • 举报
回复
有谁碰倒过相似的问题没有呢?
XPingguo 2008-06-25
  • 打赏
  • 举报
回复
API 函数 MSDN 中是英语,有中文的没。
wxg22526451 2008-06-25
  • 打赏
  • 举报
回复
不会
MARK下
duyong06102002 2008-06-25
  • 打赏
  • 举报
回复
学习了,谢谢

补充一点
用搂主的方法(用waveOutGetVolume和waveOutSetVolume 来控制播放音量),
在vista下面,只能改变自己应用程序的音量,
我也是在codeproject上边找到了高人做的CoreAudioApi.dll,用它可以控制Device音量,
即控制输出设备音量
yunfeng007 2008-06-25
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 baihe_591 的回复:]
根据codeproject的wavelib类库,我自己又封装了一个类wavecontrol,添加了:播放,暂停,停止,获得文件长度,设置播放位置,获取播放位置,控制音量,播放状态....等等.这样就通过建立声卡数组,实例化wavecontrol,两个声卡就可以同时播放了,真正作到多声卡.
[/Quote]

恩恩,支持楼主开源...
zlkingdom 2008-06-25
  • 打赏
  • 举报
回复
顶一下
baihe_591 2008-06-25
  • 打赏
  • 举报
回复
根据codeproject的wavelib类库,我自己又封装了一个类wavecontrol,添加了:播放,暂停,停止,获得文件长度,设置播放位置,获取播放位置,控制音量,播放状态....等等.这样就通过建立声卡数组,实例化wavecontrol,两个声卡就可以同时播放了,真正作到多声卡.

baihe_591 2008-06-25
  • 打赏
  • 举报
回复
jinjazz说的文章出处来自codeproject,要是早知道的话,我就不用费神去看 那长篇的英文了.
jmh521 2008-06-25
  • 打赏
  • 举报
回复
路过。。。。
加载更多回复(8)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧