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!
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!
Have you looked at JSyn? I don't think the Java Core libraries can do what you want.
This Sun forum post has some interesting code for generating sin tones. Also, given that the WAV file format is not overly complicated, you could create a table representing the desired waveform and then write it to a file. There are a few examples around, e.g. a raw audio converter and how to write a wav file.
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;
}
}
Jcollider is a Java interface to the SuperCollider synthesis server. If you want to synthesize music, this will make things much easier (it abstracts away from the tone generator to a synthesizer, takes care of things like graph generation, deleting muted synths from the synthesis graph until they are needed again, patching signals between synths dynamically, etc.).