Hallo,
ich möchte gerne einen Signal Generator schreiben der ein Rechteck-Signal mit variabler Frequenz erzeugt.
Die Frequenz soll vom Benutzer per Maus in Echtzeit verändert werden können.
Mein Problem ist der Signalgenerator selbst, ich habe eine Methode implementiert (setFrequency) die die Frequenz bei Aufruf ändern soll, jedoch geschieht dies nur mit einer starken Verzögerung.
Da ich das meiste aus dieser Klasse aus Codesnippets gesammelt habe, bin ich mir nicht ganz sicher wo genau der Fehler liegen könnte oder wie dies zu beheben wäre.
Leider habe ich auch nach intensiver Suche nicht viel zu diesem Thema gefunden und hoffe nun auf Hilfe von außen!
Hier mal der Code (leider sehr lang):
in meiner Main methode erzeuge ich ein neues Objekt meines SQUPlayers [Java]SQUPlayer player = new SQUPlayer()[/Java]
und rufe die Methode
auf
Wenn ich nun den Slider und somit die Frequenz verändere geschieht dies mit großer Verzögerung.
Ich habe bereits versucht den Buffer (zeile 18 in der SQUPlayer Klasse) kleiner zu machen, das ändert jedoch garnichts.
Bin für jeden Vorschlag dankbar!
ich möchte gerne einen Signal Generator schreiben der ein Rechteck-Signal mit variabler Frequenz erzeugt.
Die Frequenz soll vom Benutzer per Maus in Echtzeit verändert werden können.
Mein Problem ist der Signalgenerator selbst, ich habe eine Methode implementiert (setFrequency) die die Frequenz bei Aufruf ändern soll, jedoch geschieht dies nur mit einer starken Verzögerung.
Da ich das meiste aus dieser Klasse aus Codesnippets gesammelt habe, bin ich mir nicht ganz sicher wo genau der Fehler liegen könnte oder wie dies zu beheben wäre.
Leider habe ich auch nach intensiver Suche nicht viel zu diesem Thema gefunden und hoffe nun auf Hilfe von außen!
Hier mal der Code (leider sehr lang):
Java:
package csig;
import javax.sound.sampled.*;
public class SQUPlayer extends Thread{
// AudioFormat Parameter
public static final int SAMPLE_RATE = 22050;
private static final int SAMPLE_SIZE = 16;
private static final int CHANNELS = 1;
private static final boolean SIGNED = true;
private static final boolean BIG_ENDIAN = true;
// Buffer Größe, verarbeiteter Chunk
public static final int BUFFER_SIZE = 1000;
public static final int SAMPLES_PER_BUFFER = BUFFER_SIZE / 2;
//Variablen
private AudioFormat format;
private Line.Info info;
private SourceDataLine auline;
private boolean done;
private byte [] sampleData = new byte[BUFFER_SIZE];
private long periodSamples;
private long sampleNumber;
//Konstruktor
public SQUPlayer() {
// Create the audio format we wish to use
format = new AudioFormat(SAMPLE_RATE, SAMPLE_SIZE, CHANNELS, SIGNED, BIG_ENDIAN);
info = new DataLine.Info(SourceDataLine.class, format);
}
//Frequency Setter
public void setFrequency(double frequency)
{
periodSamples = (long)(SQUPlayer.SAMPLE_RATE / frequency);
}
//Erzeugt Rechteck
protected double getSample() {
double value;
double x = sampleNumber / (double) periodSamples;
if (sampleNumber < (periodSamples / 2)) {
value = 1.0;
} else {
value = -1.0;
}
sampleNumber = (sampleNumber + 1) % periodSamples;
return value;
}
public int getSamples(byte [] buffer) {
int index = 0;
for (int i = 0; i < SQUPlayer.SAMPLES_PER_BUFFER; i++) {
double ds = getSample() * Short.MAX_VALUE;
short ss = (short) Math.round(ds);
buffer[index++] = (byte)(ss >> 8);
buffer[index++] = (byte)(ss & 0xFF);
}
return SQUPlayer.BUFFER_SIZE;
}
@Override
public void run() {
int nBytesRead = 0;
try {
// Get line to write data to
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
auline.start();
while ((nBytesRead != -1))
{
nBytesRead = getSamples(sampleData);
if (nBytesRead > 0)
{
auline.write(sampleData, 0, nBytesRead);
}
}
} catch(Exception e) {
e.printStackTrace();
}
finally
{
auline.drain();
auline.close();
}
}
public void startPlayer()
{
start();
}
}
in meiner Main methode erzeuge ich ein neues Objekt meines SQUPlayers [Java]SQUPlayer player = new SQUPlayer()[/Java]
und rufe die Methode
Java:
player.setFrequency(
//Hier der Wert eines Sliders zB
jSlider1.getValue()
)
//und
player.startPlayer();
auf
Wenn ich nun den Slider und somit die Frequenz verändere geschieht dies mit großer Verzögerung.
Ich habe bereits versucht den Buffer (zeile 18 in der SQUPlayer Klasse) kleiner zu machen, das ändert jedoch garnichts.
Bin für jeden Vorschlag dankbar!