MiniPlayer.bmx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. SuperStrict
  2. Framework MaxGUI.Drivers
  3. Import BRL.GLMax2D
  4. Import BRL.EventQueue
  5. Import BRL.Timer
  6. Import BRL.WavLoader
  7. Import BRL.RamStream
  8. Import BRL.Audio
  9. 'Import BRL.FreeAudioAudio
  10. Import MaxMod2.RtAudio
  11. 'Import MaxMod2.Flac
  12. Import MaxMod2.OGG
  13. Import MaxMod2.WAV
  14. 'Import MaxMod2.Dumb
  15. 'Import MaxMod2ex.MP3
  16. Incbin "eject.wav"
  17. Incbin "click.wav"
  18. ?Linux
  19. TMaxModRtAudioDriver.Init("LINUX_PULSE")
  20. ?macos
  21. TMaxModRtAudioDriver.Init("MACOS_CORE")
  22. ?win32
  23. TMaxModRtAudioDriver.Init("WINDOWS_DS")
  24. ?
  25. SetAudioDriver("MaxMod RtAudio")
  26. MaxModVerbose True
  27. New TApp
  28. Repeat
  29. WaitEvent()
  30. Forever
  31. Type TApp
  32. Field ejectsound:TSound = LoadSound("incbin::eject.wav")
  33. Field clicksound:TSound = LoadSound("incbin::click.wav")
  34. Field Stream :TChannel
  35. Field Win :TGadget = CreateWindow("MaxMod2 MiniPlayer",0,0,320,220,Null,WINDOW_TITLEBAR|WINDOW_CENTER|WINDOW_CLIENTCOORDS|WINDOW_STATUS)
  36. Field Eject :TGadget = CreateButton("Eject",5,5,60,20,Win)
  37. Field Play :TGadget = CreateButton("Play",65,5,60,20,Win)
  38. Field SeekZero :TGadget = CreateButton("|<",125,5,30,20,Win)
  39. Field Loop :TGadget = CreateButton("Loop",190,5,55,20,Win,BUTTON_CHECKBOX|BUTTON_PUSH)
  40. Field PosGroup :TGadget = CreatePanel(5,25,310,50,Win,PANEL_GROUP|PANEL_BORDER,"Position")
  41. Field Slider :TGadget = CreateSlider(0,0,ClientWidth(PosGroup)-75,ClientHeight(PosGroup),PosGroup,SLIDER_TRACKBAR|SLIDER_HORIZONTAL)
  42. Field TimeText :TGadget = CreateLabel("00:00:00.000",ClientWidth(PosGroup)-75,0,70,12,PosGroup,LABEL_CENTER)
  43. Field SizeText :TGadget = CreateLabel("00:00:00.000",ClientWidth(PosGroup)-75,11,70,12,PosGroup,LABEL_CENTER)
  44. Field VolGroup :TGadget = CreatePanel(5,75,100,40,Win,PANEL_GROUP|PANEL_BORDER,"Volume")
  45. Field VolSlider :TGadget = CreateSlider(0,0,ClientWidth(VolGroup),ClientHeight(VolGroup),VolGroup,SLIDER_TRACKBAR|SLIDER_HORIZONTAL)
  46. Field RateGroup :TGadget = CreatePanel(110,75,100,40,Win,PANEL_GROUP|PANEL_BORDER,"Pitch")
  47. Field RateSlider:TGadget = CreateSlider(0,0,ClientWidth(RateGroup),ClientHeight(RateGroup),RateGroup,SLIDER_TRACKBAR|SLIDER_HORIZONTAL)
  48. Field PanGroup :TGadget = CreatePanel(215,75,100,40,Win,PANEL_GROUP|PANEL_BORDER,"Pan")
  49. Field PanSlider :TGadget = CreateSlider(0,0,ClientWidth(PanGroup),ClientHeight(PanGroup),PanGroup,SLIDER_TRACKBAR|SLIDER_HORIZONTAL)
  50. Field WavGroup :TGadget = CreatePanel(5,115,310,100,Win,PANEL_GROUP|PANEL_BORDER,"Waveform")
  51. Field WavCanvas :TGadget = CreateCanvas(0,0,ClientWidth(WavGroup),ClientHeight(WavGroup),WavGroup,PANEL_BORDER)
  52. Field Timer :TTimer = CreateTimer(30)
  53. Field LoopMode :Int
  54. Field Status :Int
  55. Field L:Double,R:Double
  56. Field Pitch :Double = 1
  57. Field scopesize:Int = 512+35
  58. Field scope:Float[scopesize*2]
  59. Method New()
  60. SetSliderRange(VolSlider,0,256)
  61. SetSliderValue(VolSlider,128)
  62. SetSliderRange(RateSlider,0,256)
  63. SetSliderValue(RateSlider,128)
  64. SetSliderRange(PanSlider,0,256)
  65. SetSliderValue(PanSlider,128)
  66. AddHook EmitEventHook,eventhook,Self
  67. If AppArgs.Length=>2
  68. Print AppArgs[1]
  69. OpenAudio(AppArgs[1])
  70. EndIf
  71. EndMethod
  72. Function eventhook:Object(id:Int,data:Object,context:Object)
  73. If TApp(context) Then TApp(context).OnEvent(TEvent(data))
  74. Return data
  75. End Function
  76. Method OnEvent(event:TEvent)
  77. Select event.id
  78. Case EVENT_WINDOWCLOSE
  79. If Event.Source=Win Then End
  80. Case EVENT_GADGETACTION
  81. Select Event.Source
  82. Case Eject
  83. PlaySound(ejectsound)
  84. OpenAudio( RequestFile( "", MusicExtensions() ) )
  85. Case Play
  86. PlaySound(clicksound)
  87. If Stream
  88. If Status=0
  89. Status=1
  90. ResumeChannel Stream
  91. SetGadgetText(Play,"Pause")
  92. Else
  93. Status=0
  94. PauseChannel Stream
  95. SetGadgetText(Play,"Play")
  96. EndIf
  97. EndIf
  98. Case Loop
  99. PlaySound(clicksound)
  100. If LoopMode=0 Then LoopMode=1 Else LoopMode=0
  101. If Stream SetChannelLoop(Stream,LoopMode)
  102. SetStatusText Win,"LoopMode="+LoopMode
  103. Case Slider
  104. Local pos:Int = Event.Data*512
  105. SetStatusText Win,"Seek="+pos
  106. If Stream ChannelSeek(Stream,pos,MM_SAMPLES)
  107. Case VolSlider
  108. Local vol! = (1!/128)*Event.Data
  109. SetStatusText Win,"Volume="+Float(vol)
  110. If Stream SetChannelVolume(Stream,Float(vol))
  111. Case RateSlider
  112. Pitch = 1+((1!/128)*(Event.Data-128))
  113. SetStatusText Win,"Rate="+Float(pitch)
  114. If Stream SetChannelRate(Stream,Float(pitch))
  115. Case PanSlider
  116. Local pan! = (1!/128)*(Event.Data-128)
  117. SetStatusText Win,"Pan="+Float(pan)
  118. If Stream SetChannelPan(Stream,Float(pan))
  119. Case SeekZero
  120. If Stream ChannelSeek(Stream,0)
  121. EndSelect
  122. Case EVENT_TIMERTICK
  123. RedrawGadget(WavCanvas)
  124. If Event.Source=Timer And Stream
  125. If Not ChannelPlaying(Stream)
  126. If Status=1 Then Status=0
  127. SetGadgetText(Play,"Play")
  128. Return
  129. EndIf
  130. SetGadgetText(SizeText,Millisecs2Time(GetChannelLength(Stream,MM_MILLISECS)))
  131. SetSliderValue(Slider,GetChannelPosition(Stream,MM_SAMPLES)/512)
  132. SetGadgetText(TimeText,Millisecs2Time(GetChannelPosition(Stream,MM_MILLISECS)))
  133. EndIf
  134. Case EVENT_GADGETPAINT
  135. If Event.Source=WavCanvas
  136. MaxModFillScope(scope,scopesize)
  137. SetGraphics CanvasGraphics(WavCanvas)
  138. Cls
  139. SetBlend(LIGHTBLEND)
  140. Local h:Int = ClientHeight(WavCanvas)/2
  141. Local w:Int = ClientWidth(WavCanvas)
  142. Local n:Int,x:Int
  143. SetColor(0,255,255)
  144. For n=0 Until scopesize Step 2
  145. Plot x,h+(h*scope[n])
  146. x:+1
  147. Next
  148. x=0
  149. SetColor(255,255,0)
  150. For n=1 Until scopesize Step 2
  151. Plot x,h+(h*scope[n])
  152. x:+1
  153. Next
  154. GetChannelUV(Stream,L,R)
  155. h = ClientHeight(WavCanvas)
  156. L = (h-2)*L
  157. R = (h-2)*R
  158. SetColor(0,255,255)
  159. DrawRect w-20,Float((h-1)-L),9,Float(L)
  160. SetColor(255,255,0)
  161. DrawRect w-10,Float((h-1)-R),9,Float(R)
  162. Flip
  163. EndIf
  164. EndSelect
  165. End Method
  166. Method OpenAudio(file$,inc:Int=False)
  167. If FileType(file)<>FILETYPE_FILE And inc=False Then Return
  168. If Stream Then StopChannel(Stream)
  169. Local TempStream:TChannel = CueMusic(File,LoopMode)
  170. If Not TempStream Notify "Unable to Stream Music" ; Return
  171. Stream = TempStream
  172. SetGadgetText(Win,StripAll(File)+" - "+"MaxMod2 MiniPlayer")
  173. SetGadgetText(SizeText,Millisecs2Time(GetChannelLength(Stream,MM_MILLISECS)))
  174. SetGadgetText(Play,"Pause") ; Status=1
  175. SetSliderRange(Slider,0,GetChannelLength(Stream,MM_SAMPLES)/512)
  176. SetChannelVolume(Stream,Float((1!/128)*SliderValue(VolSlider)))
  177. SetChannelRate(Stream,Float((1!/128)*SliderValue(RateSlider)))
  178. If Not ChannelSeekable(Stream)
  179. DisableGadget(Slider)
  180. Else
  181. EnableGadget(Slider)
  182. EndIf
  183. ResumeChannel Stream
  184. EndMethod
  185. Function Millisecs2Time$(Mill:Int)
  186. Local time$
  187. Local hours:Int = (Mill/(60000*60))
  188. If hours<10 Then time$:+"0"
  189. time$:+hours+":"
  190. Local mins:Int = (Mill/60000) Mod 60
  191. If mins<10 Then time$:+"0"
  192. time$:+mins+":"
  193. Local secs:Int = (Mill/1000) Mod 60
  194. If secs<10 Then time$:+"0"
  195. time$:+secs+"."
  196. Local mills:Int = Mill Mod 1000
  197. If mills<100 Then time:+"0"
  198. If mills<10 Then time:+"0"
  199. time:+mills
  200. Return time$
  201. EndFunction
  202. EndType