Reference: http://help.adobe.com/en_US/Director/11.5/UsingScripting/WS05253F9E-DF3D-4797-A0D6-3BF2F4C0BE60.html
A soundObject can be configured to receive data from user and that audio gets played. We can pass audio data using byteArray.
Following are the steps involved in passing audio data using byteArray
- Configure soundObject to read from byteArray through callback
- Prepare audio samples either by generating them or reading it from external file
- Pass the audio samples in byteArray to soundObject inside callback.
The code below configures soundObject to read from the byteArray.
--A sample code to generate a sinewave and passing it to the
audio
--engine using byteArray
global gMix, gB8BitPCMSample, gFreq
on startmovie
-- Set the frequency of the sine wave to be generated (in
Hz)
gFreq = 400.0
-- Generate and keep the sine wave PCM samples ready
generateSineWavePCMSamples()
-- Create a new Mixer
gMix = new(#mixer)
-- Set the Mixers format to that of the sound object so
that there need not be
-- any reformat of sound objects samples while mixing
gMix.sampleRate = 48000
gMix.bitDepth = 8
gMix.channelCount = 1
-- #audioInput is the callback function
-- Set the format of the sound as 48000 Hz, 8 bit, mono
-- The third parameter specifies the parent script
reference. Its optional.
so = gMix.createsoundobject("byteArraySObj", #audioInput, void,
[#samplerate:48000, #channelcount:1, #bitdepth:8])
-- Play the mixer
gMix.play()
end
The callback function that was registered will be called as soon as the soundObject is played. The inpByteArray parameter will always be of 0 length. This byteArray needs be fed with audio samples as below. Once the data passed is played the callback is called again. To stop soundObject from calling the callback we have to return false. This will change the state of the soundObject to #stopped.
-- the callback funtion for the sound object
on audioInput inpByteArray
-- Set the position from where we will write
inpByteArray.position = 1
-- Pass b8BitPCMSample.length number of data
inpByteArray.writeByteArray(gB8BitPCMSample, 1,
gB8BitPCMSample.length)
-- Make sure we are called again
return true
-- In case we should not be called again then we need to
pass false
--return false
end
The below code just generates the PCM samples once for a duration of 1 sec. This data is continuously passed to the soundObject from inside the callback function. This code needs to be called again in case the frequency of the sinewave (gFreq) is changed dynamically.
on generateSineWavePCMSamples
-- Create the byteArray which stores the PCM samples
gB8BitPCMSample = bytearray()
-- Create 1 sec buffer. Since the format of the
soundObject is
-- 48kHz, 8 bit, mono, create 48000 samples.
repeat with i = 1 to 48000
-- Get the sine value for frequency of gFreq Hz
-- Sin( 2 * PI * f ) where f varies from 0 to gFreq
sineValue = sin( 2.0 * 3.141592 * (i-1)
* gFreq / 48000.0 )
-- Convert the sineValue to 8 bit unsigned values
-- Scale the sineValue to value between 0 and 255
for 8 bit PCM
-- For simplicity we will map it from 1 to 255
sample = sineValue * 127 + 128
-- convert the sample to integer
byte = integer(sample)
-- write it into byteArray
gB8BitPCMSample.writeint8(byte)
end repeat
end
Once the data is passed to the soundObject it behaves the same way as any other soundObject. One can apply audio filters on the soundObject or Mixer, control the properties of soundObject like playRate or even apply panning on the sound Object or Mixer to get surround sound out of it. The power of this feature is only limited by one’s imagination. :)
Download the sample movie here
Feedback:
If you have any questions or comments concerning this
article, please send a message to shrinidhi@gmail.com |