瀏覽代碼

Added std.audio.

Mark Sibly 9 年之前
父節點
當前提交
3423ce8dad
共有 3 個文件被更改,包括 183 次插入0 次删除
  1. 76 0
      modules/std/audio/audiodata.monkey2
  2. 20 0
      modules/std/audio/audioformat.monkey2
  3. 87 0
      modules/std/audio/audioloader.monkey2

+ 76 - 0
modules/std/audio/audiodata.monkey2

@@ -0,0 +1,76 @@
+
+Namespace std.audio
+
+Class AudioData
+
+	Field OnDiscarded:Void()
+
+	Method New( length:Int,format:AudioFormat,hertz:Int )
+	
+		Local data:=Cast<UByte Ptr>( libc.malloc( BytesPerSample( format )*length ) )
+		
+		_length=length
+		_format=format
+		_hertz=hertz
+		_data=data
+		
+		OnDiscarded=Lambda()
+			libc.free( data )
+		End
+	End
+
+	Method New( length:Int,format:AudioFormat,hertz:Int,data:UByte ptr )
+		_length=length
+		_format=format
+		_hertz=hertz
+		_data=data
+	End
+	
+	Property Length:Int()
+	
+		Return _length
+	End
+	
+	Property Format:AudioFormat()
+		
+		Return _format
+	End
+	
+	Property Hertz:Int()
+	
+		Return _hertz
+	End
+	
+	Property Data:UByte Ptr()
+	
+		Return _data
+	End
+	
+	Property Size:Int()
+	
+		Return BytesPerSample( _format ) * _length
+	End
+	
+	Method Discard()
+		If _discarded Return
+		_discarded=True
+		OnDiscarded()
+		_length=0
+		_format=Null
+		_data=Null
+	End
+	
+	Function Load:AudioData( path:String )
+	
+		Return wavloader.LoadAudioData( path )
+	End
+	
+	Private
+	
+	Field _length:Int
+	Field _format:AudioFormat
+	Field _hertz:Int
+	Field _data:UByte Ptr
+	Field _discarded:Bool
+	
+End

+ 20 - 0
modules/std/audio/audioformat.monkey2

@@ -0,0 +1,20 @@
+
+Namespace std.audio
+
+Enum AudioFormat
+	Mono8=1
+	Mono16=2
+	Stereo8=3
+	Stereo16=4
+End
+
+Function BytesPerSample:Int( format:AudioFormat )
+	Select format
+	Case AudioFormat.Mono8 Return 1
+	Case AudioFormat.Mono16 Return 2
+	Case AudioFormat.Stereo8 Return 2
+	Case AudioFormat.Stereo16 Return 4
+	End
+	Return 0
+End
+

+ 87 - 0
modules/std/audio/audioloader.monkey2

@@ -0,0 +1,87 @@
+
+#include "<libc>"
+
+Namespace std.audio.wavloader
+
+Private
+
+Using std.stream
+
+Struct WAV_Header
+	'
+	Field RIFF:Int
+	Field len:Int
+	Field WAVE:Int
+	Field fmt:Int
+	Field headerLen:Int
+	'
+	Field formatTag:Short
+	Field numChannels:Short
+	Field samplesPerSec:Int
+	Field avgBytesPerSec:Int
+	Field blockalignment:Short
+	Field bitsPerSample:Short
+	'
+End
+
+Function ReadWAV:AudioData( stream:Stream )
+
+	Local header:=New WAV_Header
+	Local header_sz:=libc.sizeof( header )
+	
+	If stream.Read( Varptr header,header_sz )<>header_sz Return null
+
+	If header.RIFF<>$46464952 Return Null
+
+	Local format:AudioFormat
+	
+	If header.numChannels=1 And header.bitsPerSample=8
+		format=AudioFormat.Mono8
+	Else If header.numChannels=1 And header.bitsPerSample=16
+		format=AudioFormat.Mono16
+	Else If header.numChannels=2 And header.bitsPerSample=8
+		format=AudioFormat.Stereo8
+	Else If header.numChannels=2 And header.bitsPerSample=16
+		format=AudioFormat.Stereo16
+	Else
+		Return Null
+	Endif
+	
+	Local skip:=header.headerLen-16
+	If skip>0 stream.Skip( skip )
+	
+	While Not stream.Eof
+	
+		Local tag:=stream.ReadInt()
+		Local size:=stream.ReadInt()
+		
+		If tag<>$61746164	'"DATA"
+			stream.Skip( size )
+			Continue
+		Endif
+		
+		Local data:=New AudioData( size/BytesPerSample( format ),format,header.samplesPerSec )
+		
+		stream.Read( data.Data,size )
+		
+		Return data
+
+	Wend
+	
+	Return Null
+
+End
+
+Public
+
+Function LoadAudioData:AudioData( path:String )
+
+	Local stream:=Stream.Open( path,"r" )
+	If Not stream Return Null
+	
+	Local data:=ReadWAV( stream )
+	
+	stream.Close()
+	Return data
+
+End