Zum Inhalt springen

Wer kann mir helfen, einen Audio-Kanal zu buffern?


Empfohlene Beiträge

Geschrieben

Hallo zusammen,

in meiner Routine verwende ich einen Audioplayer, welcher wie folgt aufgerufen wird:

player.writeStereo(byte A, byte B);

Nun habe ich folgendes Problem:

Ich möchte ein "Pseudo Stereo" erreichen, mit einem gepufferten Kanal B.

B ist identisch mit A, wenn ich Mono abspiele.

Wie bastele ich mir nun einen Puffer dafür, so dass B mit 10ms Verzögerung abgespielt wird?

MFG

Markus

Geschrieben
Und du glaubst dir kann geholfen werden, wenn du nichtmal verrätst aus was für einem Framework diese Player Klasse kommt?

Deine erste Aufgabe sollte daher sein: Das hier lesen.

Nunja, im Prinzip ist es doch egal, aus welchem Framework dies kommt.

Es könnte auch ein ganz normaler Buffer sein, nicht für Audio sondern eine andere Verzögerung.

Hier nun die gesamte Klasse zu posten, wäre wirklich zu komplex.

Ich werd mal versuchen, ein byte[] Array zu erschaffen, welches an letzter Stelle mit dem aktuellen Byte B gefüllt wird, wovon das erste Byte gespielt wird, und welches sich mit System.ArrayCopy(....) selbst verschiebt.

Geschrieben

Hab es herausgefunden:

    /* the buffer */

    int[] circlebuffer = new int[2000];


    /* write position  */

    int writepos = (2000 - 1);


    /* read position  */

    int readpos = 0;


    /* write value into buffer and update write position */

    void buffer_write(int val) {

        circlebuffer[writepos] = val;

        writepos = (writepos + 1) % circlebuffer.length;

    }


    /* read value from buffer and update read position */

    int buffer_read() {

        int val = circlebuffer[readpos];

        readpos = (readpos + 1) % circlebuffer.length;

        return val;

    }
In meiner Routine rufe ich nun Dieses hier auf:
        if (Switches.dbeffect){

            buffer_write(rightChannel);

            rightChannel = buffer_read();

        }

        player.writeStereo(leftChannel, rightChannel);

Geschrieben

äm ich hoffe dir ist bewusst das nur Mono aus zwei boxen ist und das richtiger Stereo Sound daraus besteht das es zwei unterschiedliche Audiospuren gibt:cool:

so genug klug ges....:D

das Thema ist mal interessant :cool:

Ich versuche aus einzelnen Double werten eine Ton reihe zu generieren, leider habe ich immer ein knacken zwischen zwei tönen :eek

jemand Ahnung woran das liegt? oder wie ich das weg bekomme?


package sound.model;


import java.util.ArrayList;


import javax.sound.sampled.AudioFormat;

import javax.sound.sampled.AudioSystem;

import javax.sound.sampled.LineUnavailableException;

import javax.sound.sampled.SourceDataLine;


public class SoundGenerator {

	public SoundGenerator(){

		System.out.println("Erzeugt");

	}


	/**

	 * Generates a tone.

	 * 

	 * @param herz

	 *            Base frequency (neglecting harmonic) of the tone in cycles per

	 *            second

	 * @param milliseconds

	 *            The number of milliseconds to play the tone.

	 * @param volume

	 *            Volume, form 0 (mute) to 100 (max).

	 * @param addHarmonic

	 *            Whether to add an harmonic, one octave up.

	 */

	public void generateTone(Double herz, int milliseconds, int volume,

			boolean addHarmonic) throws LineUnavailableException {


		float frequency = 44100;

		byte[] buf;

		AudioFormat af;

		if (addHarmonic) {

			buf = new byte[2];

			af = new AudioFormat(frequency, 8, 2, true, false);

		} else {

			buf = new byte[1];

			af = new AudioFormat(frequency, 8, 1, true, false);

		}

		SourceDataLine sdl = AudioSystem.getSourceDataLine(af);

		sdl.open(af);

		sdl.start();

		for (int i = 0; i < milliseconds * frequency / 1000; i++) {

			double angle = i / (frequency / herz) * 2.0 * Math.PI;

			buf[0] = (byte) (Math.sin(angle) * volume);


			if (addHarmonic) {

				double angle2 = (i) / (frequency / herz) * 2.0 * Math.PI;

				buf[1] = (byte) (Math.sin(2 * angle2) * volume * 0.6);

				sdl.write(buf, 0, 2);

			} else {

				sdl.write(buf, 0, 1);

			}

		}

		sdl.drain();

		sdl.stop();

		sdl.close();

	}


	/**

	 * Generates a tone.

	 * 

	 * @param herz

	 *            Base frequency (neglecting harmonic) of the tone in cycles per

	 *            second

	 * @param milliseconds

	 *            The number of milliseconds to play the tone.

	 * @param volume

	 *            Volume, form 0 (mute) to 100 (max).

	 * @param addHarmonic

	 *            Whether to add an harmonic, one octave up.

	 */

	public void generateTone(ArrayList<Double> soundValues, int milliseconds, int volume,

			boolean addHarmonic) throws LineUnavailableException {


		for (Double herz : soundValues) {

			float frequency = 44100;

			byte[] buf;

			AudioFormat af;

			if (addHarmonic) {

				buf = new byte[2];

				af = new AudioFormat(frequency, 8, 2, true, false);

			} else {

				buf = new byte[1];

				af = new AudioFormat(frequency, 8, 1, true, false);

			}

			SourceDataLine sdl = AudioSystem.getSourceDataLine(af);

			sdl.open(af);

			sdl.start();

			for (int i = 0; i < milliseconds * frequency / 1000; i++) {

				double angle = i / (frequency / herz) * 2.0 * Math.PI;

				buf[0] = (byte) (Math.sin(angle) * volume);


				if (addHarmonic) {

					double angle2 = (i) / (frequency / herz) * 2.0 * Math.PI;

					buf[1] = (byte) (Math.sin(2 * angle2) * volume * 0.6);

					sdl.write(buf, 0, 2);

				} else {

					sdl.write(buf, 0, 1);

				}

			}

			sdl.drain();

			sdl.stop();

			sdl.close();


		}

	}


	private int milliseconds; 

	private int volume;

	private boolean addHarmonic;

	private float frequency = 44100;

	private byte[] buf;

	private SourceDataLine sdl;


	public void setValues( int milliseconds, int volume,

			boolean addHarmonic){

		this.milliseconds = milliseconds;

		this.volume = volume;

		this.addHarmonic = addHarmonic;

	}


	public void setMilliseconds(int milliseconds){

		this.milliseconds = milliseconds;

	}


	public void setVolume(int volume){

		this.volume = volume;

	}


	public void startSound() throws LineUnavailableException{

		AudioFormat af;

		if (addHarmonic) {

			buf = new byte[2];

			af = new AudioFormat(frequency, 8, 2, true, false);

		} else {

			buf = new byte[1];

			af = new AudioFormat(frequency, 8, 1, true, false);

		}

		sdl = AudioSystem.getSourceDataLine(af);

		sdl.open(af);

		sdl.start();


	}

	public void writeHerz(Double herz){

		for (int i = 0; i < milliseconds * frequency / 1000; i++) {

			double angle = i / (frequency / herz) * 2.0 * Math.PI;

			buf[0] = (byte) (Math.sin(angle) * volume);


			if (addHarmonic) {

				double angle2 = (i) / (frequency / herz) * 2.0 * Math.PI;

				buf[1] = (byte) (Math.sin(2 * angle2) * volume * 0.6);

				sdl.write(buf, 0, 2);

			} else {

				sdl.write(buf, 0, 1);

			}

		}

	}

	public void stopSound(){

		sdl.drain();

		sdl.stop();

		sdl.close();


	}


}


Die Tonreihe ist kein Problem aber das Knacken :(

das ich nun so viele Methoden habe liegt daran das ich bereits einiges versucht habe die reihe ohne knacken zu erzeugen, ursprünglich gab es nur die Methode generateTone(Double herz, int milliseconds, int volume,

boolean addHarmonic)

Ich hoffe das der Thread starter helfen kann ;)

Geschrieben (bearbeitet)

Ich weiss, dass ich Mono auf 2 Lautsprechern wiedergebe.

Aber durch die Verzögerung im rechten Kanal erreiche ich eine Art Raumklang ;)

-----

Auf Anhieb fällt mir nur grad auf, dass Du einen sehr kleinen Buffer verwendest.

Ausserdem:

Ändere mal:

			af = new AudioFormat(frequency, 8, 2, true, false);
zu:
			af = new AudioFormat(frequency, 8, 2, false, false);

Das sollte das Knacken beheben!

(In allen Fällen ändern)

Bearbeitet von Devilmarkus
Geschrieben

Ich glaub meine Boxen sind kaputt :D oder gehört das knacken da rein? ;)

GoWest ist aber immer noch ein guter titel

mit buffer meinst du das byte Array wie würde man dies sinnvoll vergrößern? Muss ja schließlich mit Daten gefüllt werden :)

Danke

Geschrieben
mit buffer meinst du das byte Array wie würde man dies sinnvoll vergrößern? Muss ja schließlich mit Daten gefüllt werden :)

Du füllst es doch schon mit Daten.

Fülle einfach weiter und spiele dann ab, wenn der Buffer voll ist.

Mal aus meinem Source zitiert:

    public void writeStereo(int a, int  {

        a = a ^ 0x80;

        b = b ^ 0x80;

        switch (format) {

            case SoundUtil.ULAW:

                data[offset] = SoundUtil.ulawToUPCM8((byte) a);

                data[offset + 1] = SoundUtil.ulawToUPCM8((byte) ;

                break;

            case SoundUtil.PCM8:

                data[offset] = SoundUtil.ulawToPCM8((byte) a);

                data[offset + 1] = SoundUtil.ulawToPCM8((byte) ;

                break;

            case SoundUtil.UPCM8:

                data[offset] = (byte) a;

                data[offset + 1] = (byte) b;

                break;

        }


        if ((offset += 2) == data.length) {

            line.write(data, 0, data.length);

            offset = 0;

        }

        updates++;

    }

}[/code]

Hier ist "data" mein Buffer...

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...