load_wav.monkey2 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #Import "<libc>"
  2. Namespace std.audio
  3. Private
  4. Using std.stream
  5. Struct WAV_Header
  6. Field RIFF:Int
  7. Field len:Int
  8. Field WAVE:Int
  9. End
  10. Struct FMT_Chunk
  11. Field compType:Short
  12. Field numChannels:Short
  13. Field samplesPerSec:Int
  14. Field avgBytesPerSec:Int
  15. Field blockalignment:Short
  16. Field bitsPerSample:Short
  17. End
  18. Function ReadWAV:AudioData( stream:std.stream.Stream )
  19. Local wav:=New WAV_Header
  20. Local wav_sz:=libc.sizeof( wav )
  21. If stream.Read( Varptr wav,wav_sz )<>wav_sz Return Null
  22. If wav.RIFF<>$46464952 Return Null
  23. If wav.WAVE<>$45564157 Return Null
  24. Local format:AudioFormat
  25. Local hertz:Int
  26. While Not stream.Eof
  27. Local tag:=stream.ReadInt()
  28. Local size:=stream.ReadInt()
  29. Local aligned_size:=size+(size&1) 'chunk size *including* 2 byte alignment of next chunk.
  30. Select tag
  31. Case $20746d66 'FMT
  32. Local fmt:=New FMT_Chunk
  33. Local fmt_sz:=sizeof( fmt )
  34. 'read FMT chunk data
  35. If fmt_sz>size Or stream.Read( Varptr fmt,fmt_sz )<>fmt_sz Return Null
  36. 'skip to next chunk
  37. Local n:=aligned_size-fmt_sz
  38. If n And stream.Skip( n )<>n Return Null
  39. If fmt.compType<>1 Return Null
  40. If fmt.numChannels=1 And fmt.bitsPerSample=8
  41. format=AudioFormat.Mono8
  42. Else If fmt.numChannels=1 And fmt.bitsPerSample=16
  43. format=AudioFormat.Mono16
  44. Else If fmt.numChannels=2 And fmt.bitsPerSample=8
  45. format=AudioFormat.Stereo8
  46. Else If fmt.numChannels=2 And fmt.bitsPerSample=16
  47. format=AudioFormat.Stereo16
  48. Else
  49. Return Null
  50. Endif
  51. hertz=fmt.samplesPerSec
  52. Continue
  53. Case $61746164 'DATA
  54. If Not format Return null
  55. Local bps:=BytesPerSample( format )
  56. Local length:=aligned_size/bps
  57. Local data:=New AudioData( length,format,hertz )
  58. stream.Read( data.Data,length*bps )
  59. Return data
  60. End
  61. 'skip to next chunk
  62. If stream.Skip( aligned_size )<>aligned_size Return Null
  63. Wend
  64. Return Null
  65. End
  66. Internal
  67. Function LoadAudioData_WAV:AudioData( path:String )
  68. Local stream:=std.stream.Stream.Open( path,"r" )
  69. If Not stream Return Null
  70. Local data:=ReadWAV( stream )
  71. stream.Close()
  72. Return data
  73. End