Attack, Decay, Sustain, Release
Let's recall the sound wave of a pure tone.
The amplitude of the vibration doesn't change. Hence the sound volume doesn't change over time.
In reality, sound volume is seldom constant. For example, if we hit a key on the piano, the sound volume go through four phases.
- Attack
The volume bursts to the maximum level in a short period of time - Decay
The volume drops a little bit - Sustain
The volume holds constant for a period - Release
The sound starts to fade out.
This is known as the ADSR envelope. The following is a visualization of the ADSR envelope.
You may think of the envelope as a multiplier function. If we apply the envelope to our pure tone sine wave, the result would become :
Simplified Model
While ADSR is a good mathematical model for musical intrusment, it is a bit too complicated for our simple program. Hence we will use a simpler model. Our new model will contain two phases only, the sustain and the release phase. To further simplified the model, we will use linear fade out. The multiplier function would become :Implementation
The implementation of linear fade out is very simple. It just involves a few lines of modifications of the beeping program in part 1.
// modifications of Beep.java double fade=1; int decay=sampleLength*1/3; // start fade out at 2/3 of the total time if (i>=sampleLength-1-decay) fade=(double)(sampleLength-1-i)/decay; short amplitude = (short) (volume*fade*sinValue);
Full Source Code
/****************************************************************************** * File : FadeBeep.java * Author : http://java.macteki.com/ * Description : * Play a pure tone with specified frequency, with fade out effect * Tested with : JDK 1.6 ******************************************************************************/ class FadeBeep { static void beep(double frequency, int duration) throws Exception { int nChannel = 1; // number of channel : 1 or 2 // samples per second float sampleRate = 16000; // valid:8000,11025,16000,22050,44100 int nBit = 16; // 8 bit or 16 bit sample int bytesPerSample = nChannel*nBit/8; double durationInSecond = (double) duration/1000.0; int bufferSize = (int) (nChannel*sampleRate*durationInSecond*bytesPerSample); byte[] audioData = new byte[bufferSize]; // "type cast" to ShortBuffer java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.wrap(audioData); java.nio.ShortBuffer shortBuffer = byteBuffer.asShortBuffer(); int sampleLength = audioData.length/bytesPerSample; // generate the sine wave double volume = 8192; // 0-32767 double PI = Math.PI; for(int i = 0; i < sampleLength; i++){ double time = i/sampleRate; double freq = frequency; double angle = 2*PI*freq*time; double sinValue = Math.sin(angle); double fade=1; int decay=sampleLength*1/3; // start fade out at 2/3 of the total time if (i>=sampleLength-1-decay) fade=(double)(sampleLength-1-i)/decay; short amplitude = (short) (volume*fade*sinValue); for (int c=0;c<nChannel;c++) { shortBuffer.put(amplitude); } }//end generating sound wave sample boolean isSigned=true; boolean isBigEndian=true; // Define audio format javax.sound.sampled.AudioFormat audioFormat = new javax.sound.sampled.AudioFormat(sampleRate, nBit, nChannel, isSigned,isBigEndian); javax.sound.sampled.DataLine.Info dataLineInfo = new javax.sound.sampled.DataLine.Info( javax.sound.sampled.SourceDataLine.class, audioFormat); // get the SourceDataLine object javax.sound.sampled.SourceDataLine sourceDataLine = (javax.sound.sampled.SourceDataLine) javax.sound.sampled.AudioSystem.getLine(dataLineInfo); sourceDataLine.open(audioFormat); sourceDataLine.start(); // actually play the sound sourceDataLine.write(audioData,0,audioData.length); // "flush", wait until the sound is completed sourceDataLine.drain(); } public static void main(String[] args) throws Exception { int frequency=400; // hz int duration =2000; // milliseconds beep(frequency,duration); } }
Thanks for sharing this example. I have a question though, would it be the same using for instance a wav file that is on a device? You have any tutorials with that?
ReplyDeleteYes, go to the featured page and locate part 5 of sound programming.
DeleteThanks for reading.
Your example in Lesson 5 helped me. Thank you very much for sharing :D
Delete