Программная регулировка звука в системе на C#
Я хочу в программе на время отключать звук(громкость) а когда он мне понадобится - включать на нужное положение(значение)!
Кроме некоторых моментов мне нужна абсолютная тишина в системе!
Только как это можно просто сделать!?
Вот тебе код. Не расстраивайся, все будет хорошо.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows;
using System.Runtime.InteropServices;
namespace VolumeOff
{
[StructLayout(LayoutKind.Sequential)]
public struct WAVEFORMATEX
{
public ushort wFormatTag;
public ushort nChannels;
public uint nSamplesPerSec;
public uint nAvgBytesPerSec;
public ushort nBlockAlign;
public ushort wBitsPerSample;
public ushort cbSize;
}
public partial class Form1 : Form
{
public const uint WAVE_MAPPER = unchecked((uint)(-1));
public Form1()
{
InitializeComponent();
}
[DllImport("winmm.dll", SetLastError = true)]
public static extern uint waveOutOpen(ref uint hWaveOut, uint uDeviceID, ref WAVEFORMATEX lpFormat, uint dwCallback, uint dwInstance, uint dwFlags);
[DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint waveOutGetVolume(uint hwo, ref uint dwVolume);
[DllImport("winmm.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public static extern int waveOutSetVolume(uint uDeviceID, uint dwVolume);
[DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint waveOutClose(uint hwo);
[DllImport("Kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
static extern void ZeroMemory(ref WAVEFORMATEX dest, int size);
private void button1_Click(object sender, EventArgs e)
{
uint volume = 0;
unsafe
{
uint hWO = 0;
WAVEFORMATEX waveF = new WAVEFORMATEX();
ZeroMemory(ref waveF, sizeof(WAVEFORMATEX));
waveOutOpen(ref hWO, WAVE_MAPPER, ref waveF, 0, 0, 0);
waveOutGetVolume(hWO, ref volume);
waveOutClose(hWO);
}
textBox1.Text = volume.ToString();
}
private void button2_Click(object sender, EventArgs e)
{
unsafe
{
uint hWO = 0;
WAVEFORMATEX waveF = new WAVEFORMATEX();
ZeroMemory(ref waveF, sizeof(WAVEFORMATEX));
waveOutOpen(ref hWO, WAVE_MAPPER, ref waveF, 0, 0, 0);
waveOutSetVolume(hWO, Convert.ToUInt32(textBox1.Text.ToString()));
waveOutClose(hWO);
}
}
}
}
Помню тоже когда-то страдал таким, правда на плюсах, но это было давно...
удачи с шарпом
Спасибо за ответ!
Я все же поискал в инете с большим упорством и настойчивостью и нашел вот эту ссылочку(на данный момент она рабочая) - http://www.geekpedia.com/prog_ttrls_print.php?id=176
Сам же сделал в своей проге так:
uint CurrVol = 0;
waveOutGetVolume(IntPtr.Zero, out CurrVol);
ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
MessageBox.Show(Convert.ToString(CalcVol));
int NewVolume = 0;
uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
Скажу чесно - не всё понимаю, но работает! Проверял!
В каждом деле нужно немного упорства, трудолюбие и везение!
Кто ищет тот всегда находит!!!
Удачи Вам!;)
вышеуказанный код был переписан с плюсов на шарп, почищен
и выглядит понятней
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VolumeOff
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint waveOutGetVolume(uint hwo, ref uint dwVolume);
[DllImport("winmm.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public static extern int waveOutSetVolume(uint uDeviceID, uint dwVolume);
private void button1_Click(object sender, EventArgs e)
{
uint volume = 0;
uint hWO = 0;
waveOutGetVolume(hWO, ref volume);
textBox1.Text = volume.ToString();
}
private void button2_Click(object sender, EventArgs e)
{
uint hWO = 0;
waveOutSetVolume(hWO, Convert.ToUInt32(textBox1.Text.ToString()));
}
}
}
В аттаче приложение - VolumeOff.zip
Коллеги, помогите плиз, я не могу связать позицию файла с трек баром.
В гугле наковырял такой вот примерчик:
{
if (trackBar1.Value < trackBar1.Maximum)
{
label2.Text = trackBar1.Value.ToString();
string trackBar = Convert.ToString(scrollTimer.Interval);
trackBar1.Value += 1;
trackBar1.Value = (int)(this.CurrentPosition / 1000);
}
else
{
trackBar1.Value = 0;
scrollTimer.Enabled = false;
}
}
public void Seek(ulong Millisecs)
{
if (isOpen && Millisecs <= Lng)
{
if (Pause)
{
_command = String.Format("seek MediaFile to {0}", Millisecs);
if ((Err = mciSendString(_command, null, 0, IntPtr.Zero)) != 0) OnError(new ErrorEventArgs(Err));
}
else
{
_command = String.Format("seek MediaFile to {0}", Millisecs);
if ((Err = mciSendString(_command, null, 0, IntPtr.Zero)) != 0) OnError(new ErrorEventArgs(Err));
_command = "play MediaFile";
if ((Err = mciSendString(_command, null, 0, IntPtr.Zero)) != 0) OnError(new ErrorEventArgs(Err));
}
}
}
private void CalculateLength()
{
StringBuilder str = new StringBuilder(128);
mciSendString("status MediaFile length", str, 128, IntPtr.Zero);
Lng = Convert.ToUInt64(str.ToString());
}
public ulong AudioLength
{
get
{
if (isOpen) return Lng;
else return 0;
}
}
public ulong CurrentPosition
{
get
{
if (isOpen)
{
StringBuilder s = new StringBuilder(128);
_command = "status MediaFile position";
if ((Err = mciSendString(_command, s, 128, IntPtr.Zero)) != 0) OnError(new ErrorEventArgs(Err));
return Convert.ToUInt64(s.ToString());
}
else return 0;
}
}
у меня ругается на строку например:
if ((Err = mciSendString(Pcommand, s, 128, IntPtr.Zero)) != 0) OnError(new ErrorEventArgs(Err));
мол - Err и OnError - нет такого
видать это кусок выдран откуда-то (((( может есть у кого примерчик?????
Err - интовый маркер результата.
OnError - обработчик ошибок, предположу что он в консоль или в мессагбокс выводит что то типа - "Караул товарищи, нам полный П под номером Err!".
тут собственно даже фантазия не нужна.
Err - интовый маркер результата.
OnError - обработчик ошибок, предположу что он в консоль или в мессагбокс выводит что то типа - "Караул товарищи, нам полный П под номером Err!".
тут собственно даже фантазия не нужна.
это понятно, я взял закоментил:
{
get
{
if (isOpen)
{
StringBuilder s = new StringBuilder(128);
Pcommand = "status MediaFile position";
//if ((Err = mciSendString(Pcommand, s, 128, IntPtr.Zero)) != 0) OnError(new ErrorEventArgs(Err));
return Convert.ToUInt64(s.ToString());
}
else return 0;
}
}
ползунок на одно деление сдвигается и пишет такой эксепшн
Не удалось привести тип объекта "System.Text.StringBuilder" к типу "System.IConvertible".
и указывает на строку - return Convert.ToUInt64(s.ToString());
вышеуказанный код был переписан с плюсов на шарп, почищен
и выглядит понятней
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VolumeOff
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint waveOutGetVolume(uint hwo, ref uint dwVolume);
[DllImport("winmm.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public static extern int waveOutSetVolume(uint uDeviceID, uint dwVolume);
private void button1_Click(object sender, EventArgs e)
{
uint volume = 0;
uint hWO = 0;
waveOutGetVolume(hWO, ref volume);
textBox1.Text = volume.ToString();
}
private void button2_Click(object sender, EventArgs e)
{
uint hWO = 0;
waveOutSetVolume(hWO, Convert.ToUInt32(textBox1.Text.ToString()));
}
}
}
В аттаче приложение - VolumeOff.zip
Спасибо, очень полезно. Работает, но немного неправильно. При такой регулировке громкости ползунок в трее (который регулирует громкость в винде) не передвигается. Такое впечатление, что мое приложение регулирует не системную громкость, а что-то другое. Так как громкость ползунка в трее никак не влияет на результат функции
И громче чем сейчас установлено в трее сделать нельзя. Только тише. Причем если в моей программе сделать 10% от максимума, выйти, а вотом опять зайти и запросить waveOutGetVolume(IntPtr hwo, out uint dwVolume);, то возвратится тоже положение МОЕГО ползунка, как и до закрытия программы. Значит что-то регулируется, но что?
Извините если очень много текста, пытался шире описать проблему. Хотя может это и не проблема.
А это потому, что Vista или Win7. Там надо через WSAPI звуком управлять. Старым способом (через winmm.dll) только локально для приложения звук регулируется.
Нет) Мое приложение использует другую библиотеку на Win7 и там прекрасно работает, даже лучше чем я ожидал (в интернете читал, что проблем много).
Проблема как раз НА ХР! Тупо регулирует глобальный звук, но не задевает ползунок винды, из-за чего получается, что настройка ползунком системы задает определенный лимит громкости для моего приложения.
Интересный факт: если хоть один регулятор (мой или системы) установить на 0 - звука в системе не будет) Вообще никакого! Так что дать мут на все таким способом можно.
Проблема как раз НА ХР! Тупо регулирует глобальный звук, но не задевает ползунок винды, из-за чего получается, что настройка ползунком системы задает определенный лимит громкости для моего приложения.
Интересный факт: если хоть один регулятор (мой или системы) установить на 0 - звука в системе не будет) Вообще никакого! Так что дать мут на все таким способом можно.
Раз в XP, значит потому, что регулируете звук WaveOut, функцией waveOutSetVolume, а надо с микшером работать.
То есть, mixerOpen(), и так далее, функциями mixer*. Там довольно сложный интерфейс. Можно ещё попробовать функцию auxSetVolume().