[audio] Remove 'clac' noise when playing wave (javasound) (#2670)
* [audio] Remove 'clac' noise when playing wav (javasound) A 'clac' can be heard at the beginning of a wav file when playing on the javasound sink. Close #2669 Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>pull/2680/head
parent
0a778df0ad
commit
fa029b265c
|
@ -25,6 +25,7 @@ import javax.sound.sampled.SourceDataLine;
|
|||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.audio.AudioStream;
|
||||
import org.openhab.core.audio.utils.AudioWaveUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -60,7 +61,10 @@ public class AudioPlayer extends Thread {
|
|||
@Override
|
||||
public void run() {
|
||||
SourceDataLine line;
|
||||
AudioFormat audioFormat = convertAudioFormat(this.audioStream.getFormat());
|
||||
|
||||
org.openhab.core.audio.AudioFormat openhabAudioFormat = audioStream.getFormat();
|
||||
|
||||
AudioFormat audioFormat = convertAudioFormat(openhabAudioFormat);
|
||||
if (audioFormat == null) {
|
||||
logger.warn("Audio format is unsupported or does not have enough details in order to be played");
|
||||
return;
|
||||
|
@ -87,6 +91,11 @@ public class AudioPlayer extends Thread {
|
|||
int nRead = 0;
|
||||
byte[] abData = new byte[65532]; // needs to be a multiple of 4 and 6, to support both 16 and 24 bit stereo
|
||||
try {
|
||||
// If this is a wav container, we should remove the header from the stream
|
||||
// to avoid a "clack" noise at the beginning
|
||||
if (org.openhab.core.audio.AudioFormat.CONTAINER_WAVE.equals(openhabAudioFormat.getContainer())) {
|
||||
AudioWaveUtils.removeFMT(audioStream);
|
||||
}
|
||||
while (-1 != nRead) {
|
||||
nRead = audioStream.read(abData, 0, abData.length);
|
||||
if (nRead >= 0) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package org.openhab.core.audio.utils;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
@ -31,6 +32,11 @@ import org.openhab.core.audio.AudioFormat;
|
|||
@NonNullByDefault
|
||||
public class AudioWaveUtils {
|
||||
|
||||
/**
|
||||
* This "magic" packet marks the beginning of the read data
|
||||
*/
|
||||
private final static int DATA_MAGIC = 0x64617461;
|
||||
|
||||
private static final AudioFormat DEFAULT_WAVE_AUDIO_FORMAT = new AudioFormat(AudioFormat.CONTAINER_WAVE,
|
||||
AudioFormat.CODEC_PCM_SIGNED, false, 16, 705600, 44100L, 1);
|
||||
|
||||
|
@ -69,4 +75,26 @@ public class AudioWaveUtils {
|
|||
inputStream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove FMT block (WAV header) from a stream by consuming it until
|
||||
* the magic packet signaling data. Limit to 200 readInt() (arbitrary value
|
||||
* used in sun audio package).
|
||||
* If you don't remove/consume the FMT and pass the data to a player
|
||||
* as if it is a pure PCM stream, it could try to play it and will
|
||||
* do a "click" noise at the beginning.
|
||||
*
|
||||
* @param audio A wav container in an InputStream
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void removeFMT(InputStream data) throws IOException {
|
||||
DataInputStream dataInputStream = new DataInputStream(data);
|
||||
Integer nextInt = dataInputStream.readInt();
|
||||
int i = 0;
|
||||
while (nextInt != DATA_MAGIC && i < 200) {
|
||||
nextInt = dataInputStream.readInt();
|
||||
i++;
|
||||
}
|
||||
dataInputStream.readInt();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue