Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does java have built in libraries for audio _synthesis_?

Tags:

java

audio

Note: I do NOT want to "read audio file foo.bar and play it."

I want to programmatically generate audio files on the fly and play them.

Does Java have built in libraries for this, or does this fall into the system-dependent libraries?

Thanks!

like image 837
anon Avatar asked Jan 14 '10 12:01

anon


People also ask

Can you play audio in Java?

Java API Support for MP3 Format. Currently, both Clip and SourceDataLine can play audio files in AIFC, AIFF, AU, SND, and WAV formats. We can check the supported audio format using AudioSystem: Type[] list = AudioSystem.


2 Answers

Using Andrew's approach, here's an example that plays an equal tempered scale.

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

public class Tone {

    public static void main(String[] args) throws LineUnavailableException {
        final AudioFormat af =
            new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true);
        SourceDataLine line = AudioSystem.getSourceDataLine(af);
        line.open(af, Note.SAMPLE_RATE);
        line.start();
        for  (Note n : Note.values()) {
            play(line, n, 500);
            play(line, Note.REST, 10);
        }
        line.drain();
        line.close();
    }

    private static void play(SourceDataLine line, Note note, int ms) {
        ms = Math.min(ms, Note.SECONDS * 1000);
        int length = Note.SAMPLE_RATE * ms / 1000;
        int count = line.write(note.data(), 0, length);
    }
}

enum Note {

    REST, A4, A4$, B4, C4, C4$, D4, D4$, E4, F4, F4$, G4, G4$, A5;
    public static final int SAMPLE_RATE = 16 * 1024; // ~16KHz
    public static final int SECONDS = 2;
    private byte[] sin = new byte[SECONDS * SAMPLE_RATE];

    Note() {
        int n = this.ordinal();
        if (n > 0) {
            double exp = ((double) n - 1) / 12d;
            double f = 440d * Math.pow(2d, exp);
            for (int i = 0; i < sin.length; i++) {
                double period = (double)SAMPLE_RATE / f;
                double angle = 2.0 * Math.PI * i / period;
                sin[i] = (byte)(Math.sin(angle) * 127f);
            }
        }
    }

    public byte[] data() {
        return sin;
    }
}

This low-level approach may be suitable for older, less capable platforms. Also consider javax.sound.midi; a complete example is shown here and the Synthesizing Sound tutorial is cited here.

like image 148
trashgod Avatar answered Sep 20 '22 12:09

trashgod


The easiest way to do this is with java's in built MIDI libraries:

int channel = 0; // 0 is a piano, 9 is percussion, other channels are for other instruments

    int volume = 80; // between 0 et 127
    int duration = 200; // in milliseconds

    try {
        Synthesizer synth = MidiSystem.getSynthesizer();
        synth.open();
        MidiChannel[] channels = synth.getChannels();

        // --------------------------------------
        // Play a few notes.
        // The two arguments to the noteOn() method are:
        // "MIDI note number" (pitch of the note),
        // and "velocity" (i.e., volume, or intensity).
        // Each of these arguments is between 0 and 127.
        channels[channel].noteOn( 60, volume ); // C note
        Thread.sleep( duration );
        channels[channel].noteOff( 60 );
        channels[channel].noteOn( 62, volume ); // D note
        Thread.sleep( duration );
        channels[channel].noteOff( 62 );
        channels[channel].noteOn( 64, volume ); // E note
        Thread.sleep( duration );
        channels[channel].noteOff( 64 );

        Thread.sleep( 500 );

        // --------------------------------------
        // Play a C major chord.
        channels[channel].noteOn( 60, volume ); // C
        channels[channel].noteOn( 64, volume ); // E
        channels[channel].noteOn( 67, volume ); // G
        Thread.sleep( 3000 );
        channels[channel].allNotesOff();
        Thread.sleep( 500 );



        synth.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
like image 38
user2731117 Avatar answered Sep 19 '22 12:09

user2731117