test4.monkey2 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #rem
  2. Proof of concept for music playback in monkey2!
  3. #end
  4. Namespace myapp
  5. #Import "<std>"
  6. #Import "<mojo>"
  7. #Import "<thread>"
  8. #Import "<stb-vorbis>"
  9. #Import "threads.ogg"
  10. Using std..
  11. Using mojo..
  12. Using libc
  13. Using openal
  14. Using stb.vorbis
  15. Function PlayMusic:Bool( path:String,finished:Void()=Null )
  16. Local file:=OpenCFile( path,"r" )
  17. If Not file
  18. Print "Failed to open file '"+path+"'"
  19. Return False
  20. Endif
  21. Local error:Int=0
  22. Local vorbis:=stb_vorbis_open_file( file,0,Varptr error,Null )
  23. If Not vorbis
  24. Print "Failed to open stb_vorbis, error="+error
  25. fclose( file )
  26. Return False
  27. Endif
  28. 'OK, we're doing it!
  29. New Thread( Lambda()
  30. Const buffer_ms:UInt=100
  31. Const numbufs:=3
  32. Local info:=stb_vorbis_get_info( vorbis )
  33. Local format:=info.channels=2 ? AL_FORMAT_STEREO16 Else AL_FORMAT_MONO16
  34. Local nsamples:=buffer_ms*info.sample_rate/1000
  35. Local buffer_size:=nsamples * (info.channels=2 ? 4 Else 2)
  36. Local vorbis_data:=Cast<Short Ptr>( GCMalloc( buffer_size ) )
  37. Local source:ALuint
  38. alGenSources( 1,Varptr source )
  39. Const buffers:=New ALuint[numbufs]
  40. alGenBuffers( numbufs,buffers.Data )
  41. Local n:=buffer_size
  42. For Local i:=0 Until numbufs
  43. If n n=stb_vorbis_get_samples_short_interleaved( vorbis,info.channels,vorbis_data,buffer_size/2 )
  44. alBufferData( buffers[i],format,vorbis_data,buffer_size,info.sample_rate )
  45. Next
  46. alSourceQueueBuffers( source,numbufs,buffers.Data )
  47. alSourcePlay( source )
  48. Print "Playing music..."
  49. Repeat
  50. 'decode more...
  51. If n n=stb_vorbis_get_samples_short_interleaved( vorbis,info.channels,vorbis_data,buffer_size/2 )
  52. Local state:ALenum
  53. Repeat
  54. alGetSourcei( source,AL_SOURCE_STATE,Varptr state )
  55. If state=AL_STOPPED Exit
  56. If state=AL_PLAYING
  57. Local processed:ALint
  58. alGetSourcei( source,AL_BUFFERS_PROCESSED,Varptr processed )
  59. If processed Exit
  60. Endif
  61. Sleep( buffer_ms/2/1000.0 )
  62. Forever
  63. If state=AL_STOPPED Exit
  64. Local buffer:ALuint
  65. alSourceUnqueueBuffers( source,1,Varptr buffer )
  66. If Not n Continue
  67. alBufferData( buffer,format,vorbis_data,buffer_size,info.sample_rate )
  68. alSourceQueueBuffers( source,1,Varptr buffer )
  69. Forever
  70. print "Music done."
  71. alSourceStop( source )
  72. alDeleteBuffers( numbufs,buffers.Data )
  73. GCFree( vorbis_data )
  74. stb_vorbis_close( vorbis )
  75. fclose( file )
  76. alDeleteSources( 1,Varptr source )
  77. finished()
  78. End ).Detach()
  79. Return True
  80. End
  81. Class MyWindow Extends Window
  82. Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
  83. Super.New( title,width,height,flags )
  84. PlayMusic( "asset::threads.ogg" )
  85. End
  86. Method OnRender( canvas:Canvas ) Override
  87. App.RequestRender()
  88. canvas.DrawText( "Hello World!",Width/2,Height/2,.5,.5 )
  89. End
  90. End
  91. Function Main()
  92. New AppInstance
  93. New MyWindow
  94. App.Run()
  95. End