WMMixer.Mod 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. MODULE WMMixer; (** AUTHOR "TF"; PURPOSE "Control the mixer of the default SoundDevices device"; *)
  2. IMPORT
  3. Modules,
  4. SoundDevices, Strings, Plugins, WMComponents, WMStandardComponents, WMMessages, WMWindowManager, WMProperties;
  5. VAR
  6. device : SoundDevices.Driver;
  7. master : SoundDevices.MixerChannel;
  8. StrMixer : Strings.String;
  9. TYPE
  10. String = Strings.String;
  11. Mixer* = OBJECT(WMComponents.VisualComponent)
  12. VAR
  13. deviceName-, channelName- : WMProperties.StringProperty;
  14. name : WMStandardComponents.Label;
  15. value : WMStandardComponents.Scrollbar;
  16. mute : WMStandardComponents.Checkbox;
  17. channel : SoundDevices.MixerChannel;
  18. device : SoundDevices.Driver;
  19. PROCEDURE &Init*;
  20. BEGIN
  21. Init^;
  22. NEW(deviceName, PrototypedeviceName, NIL, NIL); properties.Add(deviceName);
  23. NEW(channelName, PrototypechannelName, NIL, NIL); properties.Add(channelName);
  24. NEW(name); name.alignment.Set(WMComponents.AlignTop); name.bounds.SetHeight(20);
  25. AddContent(name);
  26. NEW(mute); mute.alignment.Set(WMComponents.AlignBottom); mute.bounds.SetHeight(20);
  27. mute.caption.SetAOC("Mute");
  28. mute.onClick.Add(MuteChanged);
  29. AddContent(mute);
  30. NEW(value); value.alignment.Set(WMComponents.AlignClient);
  31. value.bearing.SetLeft(20); value.bearing.SetRight(20);
  32. value.onPositionChanged.Add(VolChanged);
  33. value.max.Set(255);
  34. AddContent(value);
  35. SetNameAsString(StrMixer);
  36. END Init;
  37. PROCEDURE MuteChanged(sender, data : ANY);
  38. BEGIN
  39. IF channel # NIL THEN
  40. channel.SetMute(mute.state.Get () = WMStandardComponents.Checked);
  41. END
  42. END MuteChanged;
  43. PROCEDURE RecacheProperties*;
  44. VAR s : String; dn, cn : ARRAY 128 OF CHAR;
  45. BEGIN
  46. RecacheProperties^;
  47. s := deviceName.Get(); IF s # NIL THEN COPY(s^, dn) END;
  48. s := channelName.Get(); IF s # NIL THEN COPY(s^, cn); name.caption.SetAOC(cn) END;
  49. IF device # NIL THEN device.UnregisterMixerChangeListener(MixerChangeListener) END;
  50. FindChannel(dn, cn, device, channel);
  51. IF channel # NIL THEN
  52. sequencer.ScheduleEvent(SELF.MixerChangeEvent, device, channel)
  53. END;
  54. IF device # NIL THEN device.RegisterMixerChangeListener(MixerChangeListener) END;
  55. END RecacheProperties;
  56. PROCEDURE MixerChangeListener(channel : SoundDevices.MixerChannel);
  57. BEGIN
  58. sequencer.ScheduleEvent(SELF.MixerChangeEvent, device, channel)
  59. END MixerChangeListener;
  60. PROCEDURE MixerChangeEvent(sender, data : ANY);
  61. VAR vol : LONGINT; m : BOOLEAN;
  62. BEGIN
  63. IF (data = channel) & (channel # NIL) THEN
  64. vol := channel.GetVolume();
  65. m := channel.GetIsMute();
  66. value.pos.Set(255 - vol);
  67. IF m THEN mute.state.Set(WMStandardComponents.Checked)
  68. ELSE mute.state.Set(WMStandardComponents.Unchecked)
  69. END;
  70. END;
  71. END MixerChangeEvent;
  72. PROCEDURE VolChanged(sender, data : ANY);
  73. BEGIN
  74. IF channel # NIL THEN
  75. channel.SetVolume(255 - value.pos.Get())
  76. END
  77. END VolChanged;
  78. PROCEDURE FindChannel(deviceName, channelName : ARRAY OF CHAR; VAR dev : SoundDevices.Driver; VAR channel : SoundDevices.MixerChannel);
  79. VAR i : LONGINT; ch : SoundDevices.MixerChannel; name : ARRAY 128 OF CHAR;
  80. p : Plugins.Plugin;
  81. BEGIN
  82. p := SoundDevices.devices.Get(deviceName);
  83. channel := NIL;
  84. IF (p # NIL) & (p IS SoundDevices.Driver) THEN dev := p(SoundDevices.Driver) ELSE dev := NIL END;
  85. IF dev # NIL THEN
  86. FOR i := 0 TO dev.GetNofMixerChannels() - 1 DO
  87. dev.GetMixerChannel(i, ch);
  88. ch.GetName(name);
  89. IF name = channelName THEN channel := ch END;
  90. END;
  91. END
  92. END FindChannel;
  93. PROCEDURE Finalize*;
  94. BEGIN
  95. Finalize^;
  96. IF device # NIL THEN device.UnregisterMixerChangeListener(MixerChangeListener) END;
  97. END Finalize;
  98. END Mixer;
  99. KillerMsg = OBJECT
  100. END KillerMsg;
  101. Window* = OBJECT (WMComponents.FormWindow)
  102. PROCEDURE &New*;
  103. VAR vc : WMComponents.VisualComponent;
  104. BEGIN
  105. IncCount;
  106. (* To create a multi language app, try loading the respective XML instead of CreateForm()
  107. if the XML was not found or does not contain all needed elements, use CreateForm as fallback *)
  108. vc := CreateForm();
  109. Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
  110. SetContent(vc);
  111. WMWindowManager.DefaultAddWindow(SELF);
  112. SetTitle(Strings.NewString("Mixer"));
  113. END New;
  114. PROCEDURE CreateForm(): WMComponents.VisualComponent;
  115. VAR panel : WMStandardComponents.Panel;
  116. dev : SoundDevices.Driver;
  117. i : LONGINT;
  118. ch : SoundDevices.MixerChannel;
  119. name : ARRAY 128 OF CHAR;
  120. m : Mixer;
  121. CONST MWidth = 60;
  122. BEGIN
  123. dev := SoundDevices.GetDefaultDevice();
  124. NEW(panel); panel.bounds.SetExtents(MWidth * dev.GetNofMixerChannels(), 200); panel.fillColor.Set(LONGINT(0FFFFFFFFH)); panel.takesFocus.Set(TRUE);
  125. IF dev # NIL THEN
  126. FOR i := 0 TO dev.GetNofMixerChannels() - 1 DO
  127. dev.GetMixerChannel(i, ch);
  128. ch.GetName(name);
  129. NEW(m);
  130. m.alignment.Set(WMComponents.AlignLeft); m.bounds.SetWidth(MWidth);
  131. m.channelName.SetAOC(name);
  132. panel.AddContent(m);
  133. END;
  134. END;
  135. RETURN panel
  136. END CreateForm;
  137. PROCEDURE Close*;
  138. BEGIN
  139. DecCount;
  140. Close^;
  141. END Close;
  142. PROCEDURE Handle*(VAR x: WMMessages.Message);
  143. BEGIN
  144. IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN Close
  145. ELSE Handle^(x)
  146. END
  147. END Handle;
  148. END Window;
  149. VAR
  150. PrototypedeviceName, PrototypechannelName: WMProperties.StringProperty;
  151. nofWindows : LONGINT;
  152. PROCEDURE Open*;
  153. VAR inst : Window;
  154. BEGIN
  155. NEW(inst);
  156. END Open;
  157. PROCEDURE IncCount;
  158. BEGIN {EXCLUSIVE}
  159. INC(nofWindows);
  160. END IncCount;
  161. PROCEDURE DecCount;
  162. BEGIN {EXCLUSIVE}
  163. DEC(nofWindows);
  164. END DecCount;
  165. PROCEDURE MasterIncVol*;
  166. BEGIN
  167. IF master = NIL THEN
  168. device := SoundDevices.GetDefaultDevice();
  169. device.GetMixerChannel(0, master)
  170. END;
  171. IF master # NIL THEN
  172. master.SetVolume(MIN(255, master.GetVolume() + 4))
  173. END;
  174. END MasterIncVol;
  175. PROCEDURE MasterDecVol*;
  176. BEGIN
  177. IF master = NIL THEN
  178. device := SoundDevices.GetDefaultDevice();
  179. device.GetMixerChannel(0, master)
  180. END;
  181. IF master # NIL THEN
  182. master.SetVolume(MAX(0, master.GetVolume() - 4))
  183. END;
  184. END MasterDecVol;
  185. PROCEDURE Cleanup;
  186. VAR die : KillerMsg;
  187. msg : WMMessages.Message;
  188. m : WMWindowManager.WindowManager;
  189. BEGIN {EXCLUSIVE}
  190. NEW(die); msg.ext := die; msg.msgType := WMMessages.MsgExt;
  191. m := WMWindowManager.GetDefaultManager();
  192. m.Broadcast(msg);
  193. AWAIT(nofWindows = 0)
  194. END Cleanup;
  195. BEGIN
  196. Modules.InstallTermHandler(Cleanup);
  197. NEW(PrototypedeviceName, NIL, Strings.NewString(""), Strings.NewString("Name of the associated sound device"));
  198. NEW(PrototypechannelName, NIL, Strings.NewString("MasterVol"), Strings.NewString("Name of the associated sound channel"));
  199. StrMixer := Strings.NewString("Mixer");
  200. END WMMixer.
  201. WMMixer.Open ~
  202. System.Free WMMixer ~
  203. WMMixer.MasterDecVol ~