Here is part of the audio class I am working on (It will have a bunch of functions like echo/reverb, envelope functions, oscillators, etc., in the future). Right now I want to make sure it is working properly cross-platform (and also, there is very little info on using audio in blitzmax, so I wanted to get something out so people dont have the sample problems I had). It is 16 bit stereo 44.1khz only, but I don't think it is worth working on anything less... most machines have more than enough memory and speed to handle that.
If people could try it out (especially Mac and Linux users, but everyone in general), and let me know if it is working properly (maybe try creating a 440 reference tone or something if you are unsure how my FM sample included in the code is supposed to sound). The main thing I am worried about is the Little Endian / Big Endian samples sounding different on different platforms. Once I know it is working properly on all platforms, then I can throw in all the fun synthesis features.
Strict
Local x:Int
Local sound:Jsound = New JSound
sound.create_sample(44100)
For x = 0 To (44100 - 1)
Local l_ch:Short = sinewave(10, sinewave(.01, 440, x), x)
Local r_ch:Short = sinewave(10, sinewave(.01, 440, x, 100), x, 100)
sound.write(x,l_ch,r_ch)
Next
Local sound_2:TSound = sound.get_sound()
PlaySound sound_2
Input x
'***********************************************************************
'sinewave(amp_prc, freq_hz, k_smp, offset)
' amp_prc - Percentage value for amplitude. You may give values greater than 100 if you want the wave overdriven.
' freq_hz - This is the frequency of the sine wave in hz (cycles per second)
' k_smp - this is a sample offset. You must run the sinewave function for each sample in a sound
' offset - this is the wave offset. It effects where in the cycle a wave begins.
'***********************************************************************
Function sinewave:Short(amp_prc:Float, freq_hz:Float, k_smp:Int, offset:Int = 0)
Const bias = 32767 'using a short, so we want a positive 16 value. Add the bias to bring wav up to positive values
Const radian = 57.2957795 'we need degrees, not radians, so we must use a conversion
Local p:Float = (44100 / freq_hz) 'this is the number of samples per wave cycle
Local amp:Float = (amp_prc / 100) * 32767 'amp is 0-1 in the equation... we are converting from a percentage from amp_prc
Local val:Float = (amp * Sin((2 * Pi * (k_smp + offset) * radian) / p)) + amp 'finally, we calculate the value
Return val
End Function
Type JSound
Field working_sample:TAudioSample
Field playing_sample:TSound
Field sound_bank:TBank
Field dur_bytes:Int
Field dur:Int
Method New()
working_sample:TAudioSample = Null
playing_sample:TSound = Null
sound_bank:TBank = Null
FlushMem
End Method
'***********************************************************************
'.create_sample(duration)
' duration - This is the number of samples in the sound. There are 44100 samples in one second of CD quality audio
'***********************************************************************
Method create_sample(duration:Int)
dur = duration;
dur_bytes = duration * 4
sound_bank:TBank = CreateBank(dur_bytes)
End Method
'***********************************************************************
'.write(offset, l_val, r_val)
' offset - this is the sample you want to set the value for.
' l_val - the is the left value of the
'***********************************************************************
Method write(offset:Int, l_val:Short, r_val:Short)
If sound_bank = Null Then Return
Local l_ch:Int = (offset * 4)
Local r_ch:Int = (offset * 4) + 2
PokeShort(sound_bank, l_ch, l_val)
PokeShort(sound_bank, r_ch, r_val)
End Method
'***********************************************************************
'.read_left(offset)
' offset - this is the sample you want to get the value for.
'***********************************************************************
Method read_left:Short(offset:Int)
Local l_ch:Int = (offset * 4)
Return PeekShort(sound_bank, l_ch)
End Method
'***********************************************************************
'.read_right(offset)
' offset - this is the sample you want to get the value for.
'***********************************************************************
Method read_right:Short(offset:Int)
Local r_ch:Int = (offset * 4) + 2
Return PeekShort(sound_bank, r_ch)
End Method
'***********************************************************************
'.get_sound()
'***********************************************************************
Method get_sound:TSound()
working_sample:TAudioSample = CreateStaticAudioSample(BankBuf(sound_bank), dur, 44100, SF_STEREO16LE)
playing_sample:TSound = LoadSound(working_sample)
FlushMem
Return playing_sample
End Method
End Type
|