About Monkey 2 › Forums › Monkey 2 Code Library › Modules/std/audio/audiodata update
This topic contains 3 replies, has 3 voices, and was last updated by 
 Mark Sibly
 1 year, 7 months ago.
- 
		AuthorPosts
 - 
		
			
				
September 2, 2017 at 11:26 am #10206
Here’s a modified version of SetSample
The original was unfinished and was just a place holder. Here is the completed version.
You can test it by using getsample and feeding the result back with setsample
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445#rem monkeydoc @hidden Sets a sample at a given sample index.@index must be in the range 0 to Length-1.@sample is a float from -1 to 1 with 0 being the zero point or no sound.@Using GetSample and manipulating the result sent back to SetSample you can:@ sample * 2 doubles the volume@ sample * 0.5 halves the volume#endMethod SetSample( index:Int, sample:Float, channel:Int = 0 )DebugAssert( index >= 0 And index < _length )Select _formatCase AudioFormat.Mono8if sample > 0 Thensample = (1.0-sample)*127Elsesample = (-sample-1.0)*127End if_data[index] = ubyte(sample)Case AudioFormat.Stereo8if sample > 0 Thensample = (1.0-sample)*127Elsesample = (-sample-1.0)*127End If_data[index*2+(channel&1)] = ubyte(sample)Case AudioFormat.Mono16sample *= 128sample = (sample+1)*255Cast<Short Ptr>( _data )[index] = ushort(sample)Case AudioFormat.Stereo16sample *= 128sample = (sample+1)*255Cast<Short Ptr>( _data )[index*2+(channel&1)] = ushort(sample)EndEndSeptember 3, 2017 at 5:21 am #10227You’ve got skill Adam! Keep it up!
September 3, 2017 at 8:39 am #10235Nice attempt but it’s not quite right – the Mono8 case at least is broken (haven’t looked at others) as it will convert 1.0 to 0 (should be 255). But this is a long overdue addition anyway so here’s my attempt:
Monkey12345678910111213141516171819202122232425262728293031323334353637Method SetSample( index:Int,sample:Float,channel:Int=0 )DebugAssert( index>=0 And index<_length )Select _formatCase AudioFormat.Mono8_data[index]=Clamp( sample * 128.0 + 128.0,0.0,255.0 )Case AudioFormat.Stereo8_data[index*2+(channel&1)]=Clamp( sample * 128.0 + 128.0,0.0,255.0 )Case AudioFormat.Mono16Cast<Short Ptr>( _data )[index]=Clamp( sample * 32768.0,-32768.0,32767.0 )Case AudioFormat.Stereo16Cast<Short Ptr>( _data )[index*2+(channel&1)]=Clamp( sample * 32768.0,-32768.0,32767.0 )EndEnd#rem monkeydoc Gets a sample at a given sample index.@index must be in the range [0,Length).#endMethod GetSample:Float( index:Int,channel:Int=0 )'Ok, note that this never returns quite +1.0 as there is one less int above 0 than below'eg: range of signed ints is [-128,+127]'DebugAssert( index>=0 And index<_length )Select _formatCase AudioFormat.Mono8Return ( _data[index] - 128.0 ) / 128.0Case AudioFormat.Stereo8Return ( _data[index*2+(channel&1)] - 128.0 ) / 128.0Case AudioFormat.Mono16Return Cast<Short Ptr>( _data )[index]/32768.0Case AudioFormat.Stereo16Return Cast<Short Ptr>( _data )[index*2+(channel&1)]/32768.0EndReturn 0EndNote that GetSample will never actually quite return +1.0 (it will return .999 etc for max sample value). This reflects the fact that there are actually fewer sample values>0 than there are <0. Googling around suggests this is the best way to handle that. You can still SetSample 1.0 for max value no problems, it just wont read back as exactly that.
September 3, 2017 at 8:40 am #10236And here’s a little test app:
Monkey123456789101112131415161718192021222324#Import "<std>"Using std..Function Main()Local data:=New AudioData[4]data[0]=New AudioData( 1,AudioFormat.Mono8,11025 )data[1]=New AudioData( 1,AudioFormat.Stereo8,11025 )data[2]=New AudioData( 1,AudioFormat.Mono16,11025 )data[3]=New AudioData( 1,AudioFormat.Stereo16,11025 )For Local i:=0 Until 4Print "i="+iFor Local f:=-1.0 To 1.0 Step .125Print "SetSample="+fdata[i].SetSample( 0,f )Print "GetSample="+data[i].GetSample( 0 )NextNextEnd - 
		AuthorPosts
 
You must be logged in to reply to this topic.