私は、USB モデムから呼び出しを行う Java プロジェクトに取り組んできました。アプリケーションは私のコンピューターでは完全に動作しますが、スペックの低いコンピューターで実行しようとすると、PC から呼び出している人のオーディオ ストリームが完全に消え、電話で完全に聞こえます。しかし、PC ユーザーに聞こえるはずの音声が遅延し (3 ~ 5 秒)、ホワイト ノイズが発生し、文字通り会話ができなくなります。
留意すべき点:
- 私のコンピューターは i3 4GB RAM ノートブックで、低スペックは Pentium 4 1GB RAM デスクトップです。
- CPU と RAM の使用率をテストしたところ、アプリケーションはコンピューターの CPU の 20 ~ 25% を消費し、低スペックのコンピューターではほぼ 100%、両方のケースで RAM から約 30 ~ 40MB を消費しました。
- アプリケーションには通話録音機能もあり、何らかの理由で出力ファイルは完全に書き込まれます (遅延や干渉はありません)。
何が問題なのか、またはどのように解決できるのかについての手がかりはありますか?
新しいスレッドを開始した後にオーディオを処理するように作成されたクラス:(ingoing call audio)
public class SerialVoiceReader implements Runnable{
/** The running. */
private volatile boolean running = true;
/** The in. */
DataInputStream in;
/** The af. */
AudioFormat af;
/** The samples per frame. */
private int samplesPerFrame = 160;
/** The audio buffer size. */
private int audioBufferSize = samplesPerFrame * 2 ; //20ms delay
private String tel;
private String timestamp;
public SerialVoiceReader ( DataInputStream in, AudioFormat af){
this.in = in;
this.af = af;
}
public void run (){
try
{
Info infos = new Info(SourceDataLine.class, af);
SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(infos);
dataLine.open(dataLine.getFormat(),audioBufferSize *2);
dataLine.start();
// set the volume up
if (dataLine.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
FloatControl volume = (FloatControl) dataLine.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(volume.getMaximum());
}
// get a field from GUI to set as part of the file name
tel = CallGUI.telField.getText();
timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(Calendar.getInstance().getTime());
// save the stream to a file to later set the header and make it .wav format
FileOutputStream fos = new FileOutputStream("Llamadas/" + timestamp + "-" + tel + "-OUT.raw");
// the audio buffer writing (this is the audio that goes out on the call)
while (running){
byte[] buffer = new byte[audioBufferSize];
int offset = 0;
int numRead = 0;
while (running && (offset < buffer.length && (numRead = this.in.read(buffer, offset, buffer.length - offset)) >= 0))
{
offset += numRead;
}
if(running && offset>=0){
dataLine.write(buffer, 0, offset);
fos.write(buffer);
}
}
dataLine.stop();
dataLine.drain();
dataLine.close();
fos.close();
}
catch ( Exception e )
{
}
}
新しいスレッドを開始した後にオーディオを処理するように作成されたクラス:(発信通話のオーディオ)
public class SerialVoiceWriter implements Runnable{
/** The running. */
private volatile boolean running = true;
/** The out. */
DataOutputStream out;
/** The af. */
AudioFormat af;
/** The samples per frame. */
private int samplesPerFrame = 160;
/** The audio buffer size. */
private int audioBufferSize = samplesPerFrame * 2; //20ms delay
private String tel;
private String timestamp;
public SerialVoiceWriter ( DataOutputStream out, AudioFormat af, Boolean playMessage)
{
this.out = out;
this.af = af;
}
public void run ()
{
try
{
Info infos = new Info(TargetDataLine.class, af);
TargetDataLine dataLine = (TargetDataLine) AudioSystem.getLine(infos);
dataLine.open(dataLine.getFormat(),audioBufferSize*2 );
dataLine.start();
tel = CallGUI.telField.getText();
timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(Calendar.getInstance().getTime());
FileOutputStream fis = new FileOutputStream("Llamadas/" + timestamp + "-" + tel + "-IN.raw");
while (running){
byte[] audioBuffer = new byte[audioBufferSize];
int offset = 0;
int numRead = 0;
while (running && (offset < audioBuffer.length && (numRead = dataLine.read(audioBuffer, offset, audioBuffer.length - offset)) > 0))
{
offset += numRead;
}
if(running && offset>=0){
this.out.write(audioBuffer);
fis.write(audioBuffer);
}
}
dataLine.flush();
dataLine.stop();
dataLine.close();
fis.close();
dataLine = null;
}
catch (Exception e )
{
}
}
アドバイスありがとう