reproducir - reproductor mp3 en java codigo
¿Cómo generar efectos de sonido en Java? (4)
Lo que desea probablemente no sea una API sólida, sino algún tipo de código de sintetizador, estoy bastante seguro de que necesita más control de controlador de sonido de bajo nivel de lo que Java permitiría (es un lenguaje interpretado que normalmente se ejecuta en un "entorno limitado").
Pero la buena noticia es que una búsqueda rápida de " sintetización de sonido java " en google reveló un complemento llamado JSyn que utiliza métodos C nativos (que supuse que era una forma de hacerlo) para generar sonido. Parece ser gratuito para uso no comercial y también está disponible en licencias comerciales. :)
Estoy buscando un código de Java que pueda usarse para generar sonido en tiempo de ejecución - NO reproducción de archivos de sonido existentes.
Por ejemplo, ¿cuál es el mejor código para generar una onda de diente de sierra a 440 Hz durante una duración de 2 milisegundos? Código fuente apreciado!
Recuerdo que mi Commodore 128 tenía un comando de sonido simple que tomaba como parámetros voz, frecuencia, forma de onda y duración para definir un sonido. Eso funcionó muy bien en muchos casos simples (juegos rápidos y sucios, experimentos con sonido, etc.).
Estoy buscando específicamente sonidos de efectos de sonido, no música o MIDI (que la biblioteca JFugue cubre bastante bien).
El marco de medios de Java hace ambas cosas. Puede reproducir sonidos grabados o utilizar la interfaz MIDI para sintetizar sus propios sonidos y música. También proporciona una API de mezclador.
Por supuesto, si conoce los detalles de la forma de onda que desea reproducir, puede "muestrear" la función a intervalos regulares y pasar las muestras resultantes a la API de reproducción, como si se tratara de un archivo de sonido pregrabado.
JM no es mantenido activamente por Sun, pero existen distribuciones que funcionan para varias plataformas.
Mi primera computadora fue la Commodore 64, y recuerdo a Tears for Fears, "Everybody Wants To Rule the World", para extraer su chip SID. No puedo decir si este emulador de Java SID puro es de código abierto o no, pero podría darle algunos consejos sobre la implementación de la funcionalidad de forma de onda y ataque de Decay-Decaimiento de mayor nivel.
Puede generar fácilmente datos de sonido muestreados en Java y reproducirlos sin usar código nativo. Si estás hablando de MIDI, las cosas pueden ser complicadas, pero no he incursionado en esa área.
Para generar datos de sonido muestreados, tiene que hacer retroceder el proceso. Vamos a actuar como A-a-D y probar una función de sonido continuo a lo largo del tiempo. Su tarjeta de sonido hace lo mismo para el audio a través de un micrófono o una línea.
Primero, elija una frecuencia de muestreo (NO la frecuencia del tono que estamos generando). Vamos con 44100 hz ya que es probable que la tasa de reproducción de la tarjeta de sonido (por lo tanto, no hay conversión de frecuencia de muestreo, eso no es fácil a menos que el hardware lo haga).
// in hz, number of samples in one second
sampleRate = 44100
// this is the time BETWEEN Samples
samplePeriod = 1.0 / sampleRate
// 2ms
duration = 0.002;
durationInSamples = Math.ceil(duration * sampleRate);
time = 0;
for(int i = 0; i < durationInSamples; i++)
{
// sample a sine wave at 440 hertz at each time tick
// substitute a function that generates a sawtooth as a function of time / freq
// rawOutput[i] = function_of_time(other_relevant_info, time);
rawOutput[i] = Math.sin(2 * Math.PI * 440 * time);
time += samplePeriod;
}
// now you can playback the rawOutput
// streaming this may be trickier
Aquí hay una muestra que podría ayudar. Esto genera ondas de pecado:
package notegenerator;
import java.io.IOException;
/**
* Tone generator and player.
*
* @author Cesar Vezga [email protected]
*/
public class Main {
public static void main(String[] args) throws IOException {
Player player = new Player();
player.play(BeachRock.getTack1(),BeachRock.getTack2());
}
}
package notegenerator;
public class BeachRock {
// GUITAR
static String gs1 = "T332 A4-E4 F#5-C6 E5-A5 T166 G5 A5 F#5 A5 F5 A5 E5-A5 E3 G3 G#3 ";
static String gs2 = "A3 A3 A3 G3 E3 E3 G3 G#3 ";
static String gs3 = "A3 A3 A3 G3 E3 A3 C4 C#4 ";
static String gs4 = gs2 + gs2 + gs2 + gs3;
static String gs5 = "D4 D4 D4 C4 A3 A3 C4 D#4 ";
static String gs6 = "D4 D4 D4 C4 A3 E3 G3 G#3 ";
static String gs7 = gs4 + gs5 + gs6 + gs2 + "A3 A3 A3 G3 E3 B3 D3 D#3 ";
static String gs8 = "E4 E4 E4 D4 B3 B3 E4 B3 " + gs6 + gs2;
static String gs9 = "x E3-B3 E3-B3 E3-B3 E3-B3 E3 G3 G#3 ";
static String gs10 = gs7 + gs8 + gs9;
static String gs11 = "A3-D4 X*7 X*16 X*5 E3 G3 G#3 ";
static String guitar = gs1 + gs10 + gs11 + gs10 + gs11 + "A3 A3 A3";
// DRUMS
static String ds1 = "D2 X D3 D3 X*2 D3 X ";
static String ds2 = "D2 X D3 D3 X D3 D3 D3 ";
static String ds3 = "D2 D3 D3 D3 D3 T83 D3 D3 T166 D3 ";
static String ds4 = ds1 + ds1 + ds1 + ds2;
static String ds5 = ds1 + ds1 + ds1 + ds3;
static String ds6 = "D2*2 D3 D3 X*2 D3*2 ";
static String ds7 = "D2*2 D3 D3 X D3 D3 D3 ";
static String ds8 = ds6 + ds6 + ds6 + ds7;
static String drums = "V25 T166 X*16 " + ds4 + ds4 + ds5 + ds8 + ds4 + ds4
+ ds5 + ds8;
public static String getTack1(){
return guitar;
}
public static String getTack2(){
return drums;
}
}
package notegenerator;
import java.util.HashMap;
/**
*
* Physics of Music - Notes
*
* Frequencies for equal-tempered scale
* This table created using A4 = 440 Hz
* Speed of sound = 345 m/s = 1130 ft/s = 770 miles/hr
*
* ("Middle C" is C4 )
*
* http://www.phy.mtu.edu/~suits/notefreqs.html
*
* @author Cesar Vezga <[email protected]>
*
*/
public class Notes {
private static final Object[] notes = {
"C0",16.35,
"C#0/Db0",17.32,
"D0",18.35,
"D#0/Eb0",19.45,
"E0",20.6,
"F0",21.83,
"F#0/Gb0",23.12,
"G0",24.5,
"G#0/Ab0",25.96,
"A0",27.5,
"A#0/Bb0",29.14,
"B0",30.87,
"C1",32.7,
"C#1/Db1",34.65,
"D1",36.71,
"D#1/Eb1",38.89,
"E1",41.2,
"F1",43.65,
"F#1/Gb1",46.25,
"G1",49.00,
"G#1/Ab1",51.91,
"A1",55.00,
"A#1/Bb1",58.27,
"B1",61.74,
"C2",65.41,
"C#2/Db2",69.3,
"D2",73.42,
"D#2/Eb2",77.78,
"E2",82.41,
"F2",87.31,
"F#2/Gb2",92.5,
"G2",98.00,
"G#2/Ab2",103.83,
"A2",110.00,
"A#2/Bb2",116.54,
"B2",123.47,
"C3",130.81,
"C#3/Db3",138.59,
"D3",146.83,
"D#3/Eb3",155.56,
"E3",164.81,
"F3",174.61,
"F#3/Gb3",185.00,
"G3",196.00,
"G#3/Ab3",207.65,
"A3",220.00,
"A#3/Bb3",233.08,
"B3",246.94,
"C4",261.63, // Middle C
"C#4/Db4",277.18,
"D4",293.66,
"D#4/Eb4",311.13,
"E4",329.63,
"F4",349.23,
"F#4/Gb4",369.99,
"G4",392.00,
"G#4/Ab4",415.3,
"A4",440.00,
"A#4/Bb4",466.16,
"B4",493.88,
"C5",523.25,
"C#5/Db5",554.37,
"D5",587.33,
"D#5/Eb5",622.25,
"E5",659.26,
"F5",698.46,
"F#5/Gb5",739.99,
"G5",783.99,
"G#5/Ab5",830.61,
"A5",880.00,
"A#5/Bb5",932.33,
"B5",987.77,
"C6",1046.5,
"C#6/Db6",1108.73,
"D6",1174.66,
"D#6/Eb6",1244.51,
"E6",1318.51,
"F6",1396.91,
"F#6/Gb6",1479.98,
"G6",1567.98,
"G#6/Ab6",1661.22,
"A6",1760.00,
"A#6/Bb6",1864.66,
"B6",1975.53,
"C7",2093.00,
"C#7/Db7",2217.46,
"D7",2349.32,
"D#7/Eb7",2489.02,
"E7",2637.02,
"F7",2793.83,
"F#7/Gb7",2959.96,
"G7",3135.96,
"G#7/Ab7",3322.44,
"A7",3520.00,
"A#7/Bb7",3729.31,
"B7",3951.07,
"C8",4186.01,
"C#8/Db8",4434.92,
"D8",4698.64,
"D#8/Eb8",4978.03
};
private HashMap<String,Double> noteMap;
public Notes(){
noteMap = new HashMap<String,Double>();
for(int i=0; i<notes.length; i=i+2){
String name = (String)notes[i];
double freq = (Double)notes[i+1];
String[] keys = name.split("/");
for(String key : keys){
noteMap.put(key, freq);
System.out.println(key);
}
}
}
public byte[] getCordData(String keys, double duration){
int N = (int) (8000 * duration/1000);
byte[] a = new byte[N+1];
String[] key = keys.split(" ");
int count=0;
for(String k : key){
double freq = getFrequency(k);
byte[] tone = tone(freq,duration);
if(count==0){
a = tone;
}else{
a = addWaves(a,tone);
}
count++;
}
return a;
}
public byte[] addWaves(byte[] a, byte[] b){
int len = Math.max(a.length, b.length);
byte[] c = new byte[len];
for(int i=0; i<c.length; i++){
byte aa = ( i < a.length ? a[i] : 0);
byte bb = ( i < b.length ? b[i] : 0);
c[i] = (byte) (( aa + bb ) / 2);
}
return c;
}
public double getFrequency(String key){
Double f = noteMap.get(key);
if(f==null){
System.out.println("Key not found. "+key);
f = 0D;
}
return f;
}
public byte[] tone(String key, double duration) {
double freq = getFrequency(key);
return tone(freq,duration);
}
public byte[] tone(double hz, double duration) {
int N = (int) (8000 * duration/1000);
byte[] a = new byte[N+1];
for (int i = 0; i <= N; i++) {
a[i] = (byte) ( Math.sin(2 * Math.PI * i * hz / 8000) * 127 );
}
return a;
}
}
package notegenerator;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class Player {
private SourceDataLine line = null;
private Notes notes = new Notes();
private long time = 250;
private double volumen = 1;
public void play(String keys) {
byte[] data = parse(keys);
start();
line.write(data, 0, data.length);
stop();
}
public void play(String... track) {
byte[] data2 = parseAll(track);
if (data2 != null) {
start();
line.write(data2, 0, data2.length);
stop();
}
}
private byte[] parseAll(String... track) {
byte[] data2 = null;
for (String t : track) {
byte[] data1 = parse(t);
if (data2 == null) {
data2 = data1;
} else {
data2 = notes.addWaves(data1, data2);
}
}
return data2;
}
private byte[] parse(String song) {
time = 250;
volumen = 1;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String[] key = song.split(" ");
byte[] data = null;
for (String k : key) {
int mult = 1;
if (k.indexOf("*") > -1) {
String keyAux = k.split("//*")[0];
mult = Integer.parseInt(k.split("//*")[1]);
k = keyAux;
} else if (k.startsWith("T")) {
time = Long.parseLong(k.substring(1));
continue;
} else if (k.startsWith("V")) {
volumen = Double.parseDouble(k.substring(1)) / 100;
if(volumen>1) volumen = 1;
if(volumen<0) volumen = 0;
continue;
}
if (k.indexOf("-") > -1) {
k = k.replaceAll("-", " ").trim();
data = notes.getCordData(k, time * mult);
} else {
data = notes.tone(k, time * mult);
}
volumen(data);
try {
baos.write(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return baos.toByteArray();
}
private void volumen(byte[] data) {
for(int i=0; i<data.length; i++){
data[i] = (byte) (data[i] * volumen);
}
}
private void stop() {
line.drain();
line.stop();
}
private void start() {
AudioFormat format = new AudioFormat(8000.0F, 8, 1, true, false);
SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class,
format); // format
// is
// an
// AudioFormat
// object
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Format not supported");
System.exit(1);
}
// Obtain and open the line.
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException ex) {
ex.printStackTrace();
}
// Assume that the TargetDataLine, line, has already
// been obtained and opened.
int numBytesRead;
line.start();
}
public void save(String track, String fname) throws IOException {
byte[] data = parse(track);
FileOutputStream fos = new FileOutputStream(fname);
fos.write(data);
fos.flush();
fos.close();
}
}