DSP tutorial: Generating a sine wave
Last modified: November 16th, 2011This example generates a sine wave and saves it in a .wav file. Sine values are also saved to a .txt file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | public class SineWaveToWav { private final static int SAMPLERATE = 44100; private final static int SAMPLESNUM = 100000; private final static int SAMPLELENGTHINBYTES = 2; // converts float array to byte array private byte[] getBytesFromDoubles(final double[] audioData, final int samplesNum, final int sampleSizeInBytes) { byte[] audioDataBytes = new byte[samplesNum * sampleSizeInBytes]; for (int i = 0; i < samplesNum; i++) { // saturation audioData[i] = Math.min(1.0, Math.max(-1.0, audioData[i])); // scaling and conversion to integer int sample = (int) Math.round((audioData[i] + 1.0) * 32767.5) - 32768; byte high = (byte) ((sample >> 8) & 0xFF); byte low = (byte) (sample & 0xFF); audioDataBytes[i * 2] = low; audioDataBytes[i * 2 + 1] = high; } return audioDataBytes; } // saves the audio data given in audioDataBytes to a .wav file private void writeWavFile(final byte[] audioDataBytes, final String fileName, final int sampleLengthInBytes) { AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, SAMPLERATE, 16, 1, sampleLengthInBytes, SAMPLERATE, false); AudioInputStream audioInputStream = new AudioInputStream(new ByteArrayInputStream(audioDataBytes), audioFormat, audioDataBytes.length / audioFormat.getFrameSize()); try { FileOutputStream fileOutputStream = new FileOutputStream(fileName); AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, fileOutputStream); audioInputStream.close(); } catch (Exception e) { e.printStackTrace(); } } public void generate() { double[] audioData = new double[SAMPLESNUM]; int samplePos = 0; int frequency = 120; double lengthInSecs = 2; // http://en.wikibooks.org/wiki/Sound_Synthesis_Theory/Oscillators_and_Wavetables for (double phase = 0; samplePos < lengthInSecs * SAMPLERATE && samplePos < SAMPLESNUM; phase += (2 * Math.PI * frequency) / SAMPLERATE) { audioData[samplePos++] = Math.sin(phase); if (phase >= 2 * Math.PI) phase -= 2 * Math.PI; } // converting double values to byte values needed for writing the .wav file byte[] audioDataBytes = getBytesFromDoubles(audioData, SAMPLESNUM, SAMPLELENGTHINBYTES); // writing text file with the values try { BufferedWriter outputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8")); for (int i = 0; i < lengthInSecs * SAMPLERATE; i++) { int sample = (int) Math.round((audioData[i] + 1.0) * 32767.5) - 32768; outputStream.write(i + ". " + Double.toString(audioData[i]) + " " + sample + "\n"); } outputStream.close(); } catch (Exception e) { e.printStackTrace(); } writeWavFile(audioDataBytes, "output.wav", SAMPLELENGTHINBYTES); } public static void main(String[] args) { SineWaveToWav sineWaveToWav = new SineWaveToWav(); sineWaveToWav.generate(); } } |
download (5.7 kb)
About me
I'm Nonoo. This is my blog about music, sounds, filmmaking, amateur radio, computers, programming, electronics and other things I'm obsessed with.
... »
Trackback URL
No comments yet.
Trackback responses to this post