Java generatoare de sunet (Programare, Java, Audio)

Hamza Yerlikaya a intrebat.

Am creat o clonă de pong și aș vrea să adaug niște efecte sonore atunci când apar coliziuni. Problema mea este că fiecare exemplu pe care l-am găsit despre sintetizarea sunetului necesită aproximativ 30 de linii de cod, având în vedere că întreaga mea aplicație are doar 90 de linii de cod. Sunt în căutarea unei abordări mai simple. Există o modalitate simplă de a crea un sunet de tip beep cu diferite tonuri? Durata nu contează. Vreau doar o serie de semnale sonore cu tonuri diferite.

Comentarii

  • 30 de linii de cod nu este mult. Ce e rău în a folosi exemplele pe care le-ați găsit? –  > Por Joe.
  • da, știu, dar întreaga clonă are 90 de linii. o treime din cod va fi folosit doar pentru a crea un simplu bip. pentru mine cam fără rost, dar dacă nu găsesc altă cale, o să merg pe asta. –  > Por Hamza Yerlikaya.
  • O pătrime din cod, după aceea. Dacă asta te face să te simți mai bine… –  > Por Sev.
4 răspunsuri
tangens

Iată un mic exemplu preluat (și prescurtat) din Java Sound – Exemplu: Cod pentru a genera un ton audio

    byte[] buf = new byte[ 1 ];;
    AudioFormat af = new AudioFormat( (float )44100, 8, 1, true, false );
    SourceDataLine sdl = AudioSystem.getSourceDataLine( af );
    sdl.open();
    sdl.start();
    for( int i = 0; i < 1000 * (float )44100 / 1000; i++ ) {
        double angle = i / ( (float )44100 / 440 ) * 2.0 * Math.PI;
        buf[ 0 ] = (byte )( Math.sin( angle ) * 100 );
        sdl.write( buf, 0, 1 );
    }
    sdl.drain();
    sdl.stop();

Comentarii

  • Poți să explici de ce înmulțești cu 100 în loc de 128 în această linie: buf[ 0 ] = (byte )( Math.sin( angle ) * 100 ); Mi se pare foarte confuz, pentru că aș bănui că semnalul ar trebui să meargă între -127 și 127 ish De asemenea, link-ul este mort. Vă rog să îl actualizați dacă este posibil. –  > Por Felix.
  • Asta va afecta doar amplitudinea (adică volumul) sunetului. –  > Por în timp ce.
  • Ce rost are i < 1000 * (float )44100 / 1000 nu este același lucru cu i < (float )44100 ? –  > Por dk14.
  • @dk14, primele 1000 îți vor permite să schimbi lungimea eșantionului, care presupun că este de milisecunde. –  > Por Firedan1176.
Bojan Vukasovic

Iată același cod ca mai sus, cu un pic de descriere pe 16 biți

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

public class MakeSound {
  public static void main(String[] args) throws LineUnavailableException {
    System.out.println("Make sound");
    byte[] buf = new byte[2];
    int frequency = 44100; //44100 sample points per 1 second
    AudioFormat af = new AudioFormat((float) frequency, 16, 1, true, false);
    SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
    sdl.open();
    sdl.start();
    int durationMs = 5000;
    int numberOfTimesFullSinFuncPerSec = 441; //number of times in 1sec sin function repeats
    for (int i = 0; i < durationMs * (float) 44100 / 1000; i++) { //1000 ms in 1 second
      float numberOfSamplesToRepresentFullSin= (float) frequency / numberOfTimesFullSinFuncPerSec;
      double angle = i / (numberOfSamplesToRepresentFullSin/ 2.0) * Math.PI;  // /divide with 2 since sin goes 0PI to 2PI
      short a = (short) (Math.sin(angle) * 32767);  //32767 - max value for sample to take (-32767 to 32767)
      buf[0] = (byte) (a & 0xFF); //write 8bits ________WWWWWWWW out of 16
      buf[1] = (byte) (a >> 8); //write 8bits WWWWWWWW________ out of 16
      sdl.write(buf, 0, 2);
    }
    sdl.drain();
    sdl.stop();
  }
}

Sev

java.awt.Toolkit.getDefaultToolkit().beep()

serie de bipuri?

int numbeeps = 10;

for(int x=0;x<numbeeps;x++)
{
  java.awt.Toolkit.getDefaultToolkit().beep();
}

Martijn Courteaux

Puteți folosi JSyn. Aceasta este o librărie pe care trebuie să o instalați (cu o .DLL și un .JAR). Dar este foarte simplu să creați tonuri diferite.

Link (Sunt disponibile și tutoriale)

Acesta este un exemplu:

public static void main(String[] args) throws Exception {
    SawtoothOscillatorBL osc;
    LineOut lineOut;
    // Start JSyn synthesizer.
    Synth.startEngine(0);

    // Create some unit generators.
    osc = new SawtoothOscillatorBL();
    lineOut = new LineOut();

    // Connect oscillator to both left and right channels of output.
    osc.output.connect(0, lineOut.input, 0);
    osc.output.connect(0, lineOut.input, 1);

    // Start the unit generators so they make sound.
    osc.start();
    lineOut.start();

    // Set the frequency of the oscillator to 200 Hz.
    osc.frequency.set(200.0);
    osc.amplitude.set(0.8);

    // Sleep for awhile so we can hear the sound.
    Synth.sleepForTicks(400);

    // Change the frequency of the oscillator.
    osc.frequency.set(300.0);
    Synth.sleepForTicks(400);

    // Stop units and delete them to reclaim their resources.
    osc.stop();
    lineOut.stop();
    osc.delete();
    lineOut.delete();

    // Stop JSyn synthesizer.
    Synth.stopEngine();
}

Martijn

Comentarii

  • JSyn este acum pur Java și nu mai necesită un DLL nativ. –  > Por philburk.

Tags:,