Veröffentlicht 1. April 201015 j Hallo zusammen, in meiner Routine verwende ich einen Audioplayer, welcher wie folgt aufgerufen wird: player.writeStereo(byte A, byte ; 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
1. April 201015 j 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.
1. April 201015 j Autor 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.
1. April 201015 j Autor 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);
1. April 201015 j Autor Hier ein Beispiel des Buffers: http://cpc-live.com/silkworm.zip Das CPC-MDL wird Mono abgespielt. Mit dem Buffer klingt es besser
7. April 201015 j ä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.... 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
7. April 201015 j Autor 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 7. April 201015 j von Devilmarkus
7. April 201015 j Autor Übrigens: Einen "Live" Test meines Effektes kann man hier hören: CPCWiki People Network - Devilmarkus's webcpc - Go West (Digiblaster) (Einfach auf das Schwarze PNG "Start Here" klicken und einen Moment warten...)
7. April 201015 j Ich glaub meine Boxen sind kaputt 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
7. April 201015 j Autor 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...
Archiv
Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.