Entwickler-Ecke

Windows API - Windows-Lautstärkeregler fernsteuern


holger - Sa 10.03.07 16:05
Titel: Windows-Lautstärkeregler fernsteuern
Hallo Leute,

ein Bekannter von mir (Musiker) möchte die Lautstärke seiner Soundkarte (Midi-Synthesizer) steuern (ohne Maus, Monitor, Tastatur).
Der Midi-Sythesizer lässt sich ja normalerweise mit der normalen Windows-Lautstärkeregelung steuern.

Für die Fernbedienung käme eine Infrarot-Fernbedienung in Frage.

Ich hätte aber noch den Vorschlag, ein Potentiometer an den Joystick-Port zu basteln.

Ich müsste also folgendes wissen:
[highlight]wie erfahre ich die Werte der Joystick-Analog-Digitalwandler,
wie verändere ich die Stellung der Lautstärkeregler,[/highlight]
wie kann man die Befehle einer IR-Fernbedienung abfragen.

Dafür gibt es garantiert Möglichkeiten mit dem API.
Darüber habe ich aber keine Dokumentation.

Hat jemand schon mal so etwas gemacht?

Ich währe dankbar für jede Information.

Tschüß und ein schönes WE
Holger


Delete - Sa 10.03.07 18:14

Hier ist was zur Lautstärke-Änderung:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
uses ...MMSystem...

var
oldVolLi,oldVolRe : Integer;


procedure TForm1.GetVolume(var volL, volR: Word);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  volL:= 0;
  volR:= 0;
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  // get volume
  waveOutGetVolume(hWO, @vol);
  volL:= vol and $FFFF;
  volR:= vol shr 16;
  waveOutClose(hWO);
end;

procedure TForm1.SetVolume(var volL, volR: Word);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  vol:= volL + volR shl 16;
  // set volume
  waveOutSetVolume(hWO, vol);
  waveOutClose(hWO);
end;

procedure TForm1.VolminusClick(Sender: TObject);
var  VolLi, VolRe: Word;
begin
   GetVolume(VolLi,VolRe);
  if (VolLi>5000) and (VolRe>5000) then
  Begin VolLi:=VolLi-5000; VolRe:=VolRe-5000;
  SetVolume(VolLi,VolRe);  // GetVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  end;
end;

procedure TForm1.VolplusClick(Sender: TObject);
var  VolLi, VolRe: Word;
begin
   GetVolume(VolLi,VolRe);
  if (VolLi<60535) and (VolRe<60535) then
  Begin VolLi:=VolLi+5000; VolRe:=VolRe+5000;
  SetVolume(VolLi,VolRe);  // GetVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  end;
end;

procedure TForm1.Volume1Click(Sender: TObject);
var  VolLi, VolRe: Word;
begin
if Mute1.checked=false then
  Begin
  GetVolume(VolLi,VolRe);
  oldVolLi:=VolLi; oldVolRe:=VolRe;
  VolLi:=0; VolRe:=0;
  SetVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  Mute1.checked:=true;
  end else
  begin
  VolLi:=oldVolLi; VolRe:=oldVolRe;
  SetVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  Mute1.checked:=false;
  end;
end;


http://www.pics-software.de/download/comps/joystick.zip

IR-FB gibt es viele, die dafür geeignet sind (IR-Empfänger mit USB)

z.B. bei PEARL:

http://www.pearl.de/product.jsp?pdid=PE4069&catid=1381&vid=916&curr=DEM


holger - So 11.03.07 18:22

Vielen Dank Hathor,

ich habe das Beispiel ausprobiert und es funktionierte sofort.
Ich hätte gar nicht gedacht, daß es diese Unit mmsystem in meinem Delphi6 schon gibt. Leider gibt es dazu so gut wie keine Hilfe.

Ich habe jetzt versucht das Programm für den Midiport zu erweitern.
( midiOutOpen(@hMO, Midi_MAPPER, 0, 0, 0); usw. )

Und ich habe einen Timer eingebaut, welcher automatisch die Prograssbars aktualisiert.(verändere ich jetzt den "Windows-Wave-Regler" so ändert sich auch meine Progressbar.

So sieht mein Prog. jetzt aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
var
oldWaveVolLi,oldWaveVolRe,
oldMidiVolLi,oldMidiVolRe : Integer;

procedure TForm1.Timer1Timer(Sender: TObject);
var  VolLi, VolRe: Word;
begin
  GetWavevolume(VolLi, VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  GetMidivolume(VolLi, VolRe);
  PbMidivolre.position:= VolRe;
  PbMidivolli.position:= Volli;
end;

procedure TForm1.GetWaveVolume(var volL, volR: Word);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  volL:= 0;
  volR:= 0;
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  // get volume
  waveOutGetVolume(hWO, @vol);
  volL:= vol and $FFFF;
  volR:= vol shr 16;
  waveOutClose(hWO);
end;

procedure TForm1.SetWaveVolume(var volL, volR: Word);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  vol:= volL + volR shl 16;
  // set volume
  waveOutSetVolume(hWO, vol);
  waveOutClose(hWO);
end;

procedure TForm1.VolminusClick(Sender: TObject);
var  VolLi, VolRe: Word;
begin
   GetWaveVolume(VolLi,VolRe);
  if (VolLi>5000) and (VolRe>5000) then
  Begin VolLi:=VolLi-5000; VolRe:=VolRe-5000;
  SetWaveVolume(VolLi,VolRe);  // GetVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  end;
end;

procedure TForm1.VolplusClick(Sender: TObject);
var  VolLi, VolRe: Word;
begin
   GetWaveVolume(VolLi,VolRe);
  if (VolLi<60535) and (VolRe<60535) then
  Begin VolLi:=VolLi+5000; VolRe:=VolRe+5000;
  SetWaveVolume(VolLi,VolRe);  // GetVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  end;
end;

procedure TForm1.Volume1Click(Sender: TObject);
var  VolLi, VolRe: Word;
begin
if Mute1.checked=false then
  Begin
  GetWaveVolume(VolLi,VolRe);
  oldWaveVolLi:=VolLi; oldWaveVolRe:=VolRe;
  VolLi:=0; VolRe:=0;
  SetWaveVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  Mute1.checked:=true;
  end else
  begin
  VolLi:=oldWaveVolLi; VolRe:=oldWaveVolRe;
  SetWaveVolume(VolLi,VolRe);
  Pbvolre.position:= VolRe;
  Pbvolli.position:= Volli;
  Mute1.checked:=false;
  end;
end;

procedure TForm1.getMidiVolume(var volL, volR: Word);
var
  hMO: HMidiOUT;
  // waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  volL:= 0;
  volR:= 0;
  // init TWAVEFORMATEX
  // FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  MidiOutOpen(@hMO, Midi_MAPPER, 0, 0, 0);
  // get volume
  midiOutGetVolume(hMO, @vol);
  volL:= vol and $FFFF;
  volR:= vol shr 16;
  midiOutClose(hmO);
end;

procedure TForm1.SetMidiVolume(var volL, volR: Word);
var
  hMO: HMidiOUT;
  //waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  // init TWAVEFORMATEX
  //FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  midiOutOpen(@hMO, Midi_MAPPER, 0, 0, 0);
  vol:= volL + volR shl 16;
  // set volume
  MidiOutSetVolume(hMO, vol);
  MidiOutClose(hMO);
end;

procedure TForm1.VolMidiMinusClick(Sender: TObject);
var  VolLi, VolRe: Word;
begin
   GetMidiVolume(VolLi,VolRe);
  if (VolLi>5000) and (VolRe>5000) then
  Begin VolLi:=VolLi-5000; VolRe:=VolRe-5000;
  SetMidiVolume(VolLi,VolRe);
  PbMidivolre.position:= VolRe;
  PbMidivolli.position:= Volli;
  end;
end;

procedure TForm1.VolMidiPlusClick(Sender: TObject);
var  VolLi, VolRe: Word;
begin
   GetMidiVolume(VolLi,VolRe);
  if (VolLi<60535) and (VolRe<60535) then
  Begin VolLi:=VolLi+5000; VolRe:=VolRe+5000;
  SetMidiVolume(VolLi,VolRe);
  PbMidivolre.position:= VolRe;
  PbMidivolli.position:= Volli;
  end;
end;

procedure TForm1.VolumeMidi1Click(Sender: TObject);
var  VolLi, VolRe: Word;
begin
if MuteMidi.checked=false then
  Begin
  GetMidiVolume(VolLi,VolRe);
  oldMidiVolLi:=VolLi; oldMidiVolRe:=VolRe;
  VolLi:=0; VolRe:=0;
  SetMidiVolume(VolLi,VolRe);
  Pbmidivolre.position:= VolRe;
  Pbmidivolli.position:= Volli;
  MuteMidi.checked:=true;
  end else
  begin
  VolLi:=oldMidiVolLi; VolRe:=oldMidiVolRe;
  SetMidiVolume(VolLi,VolRe);
  Pbmidivolre.position:= VolRe;
  Pbmidivolli.position:= Volli;
  Mutemidi.checked:=false;
  end;
end;

end.


Der Quelltext lässt sich zwar fehlerfrei compilieren, aber der Midi-Lautstäkeregler macht leider nichts.
Lediglich der linke Kanal schlägt mal kurz aus, wenn ich den Mute-Button betätige (Ein zweiter Aufruf von getMidiVolume durch den Timmer steuert die Progressbar wieder zurück).

Habe ich mit "midiOutOpen"... überhaupt richtig angesetzt?

Ich habe 0 Plan :bawling:


Danke für eure Mithilfe im Voraus
Holger
:D


Delete - So 11.03.07 20:39

Lass Dir doch mal nach dem Aufruf von GetMidiVolume(VolLi,VolRe); die Werte in 2 Labels anzeigen evtl. mit einem zusätzlichen Timer - ändert sich was nach Änderung der Windows-MIDI-Lautstärkeregelung?

ausserdem wäre es sinnvoll, unterschiedliche VAR zu verwenden,
um auszuschliessen, dass etwas mit falschen Werten gefüttert wird:
(in allen anderen Proc auch ändern)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.Timer1Timer(Sender: TObject);
var  WVolLi, WVolRe, MVolLi, MVolRe: Word;
begin
  GetWavevolume(WVolLi, WVolRe);
  Pbvolre.position:= WVolRe;
  Pbvolli.position:= WVolli;
  GetMidivolume(MVolLi, MVolRe);
  PbMidivolre.position:= MVolRe;
  PbMidivolli.position:= MVolli;
end;


holger - Mo 12.03.07 19:26

Hallo,
die Lautstärkeregelung habe ich in Griff :lol: Als nächstes kann ich mich über die Fernsteuerung her machen.

Die Midi-Steuerung ging viel einfacher zu realisieren als die Wave-Steuerung.
Dieser Code reicht aus:

Quelltext
1:
midiOutSetVolume(0, vol); // Handle muss null sein!                    


Quelltext
1:
midiOutGetVolume(0, @vol); // Handle muss null sein!                    

Erfunden habe ich das nicht selbst. Sondern es gibt ein schönes kleines OpenSource Projekt von Saubäär :
http://www.delphi-forum.de/viewtopic.php?p=427484
(In diesem Projekt steckt ein Regler für Wave und einer für Midi, und es ist dazu noch recht komfortabel.)

Tschüß erst mal....