Speex stream to wav

Hi,

I’m publishing my microphone using Speex codec from Flash to Wowza, and I want to decode the audio on the server using JSpeex.

Actually I want to save Speex audio stream into wave file.

I see similar questions on Wowza forum, but unfortunately can’t get all this working.

Can anybody post the sample which really works (including 1-bit header concatenation, etc.) ?

I will be really thankful!

WE (Wowza) do not have sample code for this.

Charlie

hi borisbsu,

I’m trying to get your example of recording an wav to work. A wav file is created but when I play the wav file the recorded sound is really distorted. It’s hard to understand the recording.

Help would be highly appreciated!

Kind Regards,

Marcel

Below is the example if anybody will look for the same question in the future:

(It’s based on the following package https://www.wowza.com/downloads/forums/videopassthru/VideoPassThru.zip)

public class MediaStreamAudioRecord extends MediaStreamLive {
public class MediaStreamAudioRecord extends MediaStreamLive {
    private int audioBytes = 0;
    private int videoBytes = 0;
    private int dataBytes = 0;
    private ByteBuffer audioBuffer = null;
    private ByteBuffer dataBuffer = null;
    private ByteBuffer videoBuffer = null;
    private AudioFileWriter spxWriter;
    private AudioFileWriter wavWriter;
    public void startPublishing() {
        super.startPublishing();
        WMSLoggerFactory.getLogger(null).info("MediaStreamAudioRecord: startPublishing");
        try {
            // Speex output
            spxWriter = new OggSpeexWriter(1 /* Wideband */, 16000, 1, 1, false);
            spxWriter.open(getStreamFileForWrite(getName(), "spx", getExt()));
            spxWriter.writeHeader("Recorded with Wowza");
            // Wave output
            wavWriter = new PcmWaveWriter(16000, 1);
            wavWriter.open(getStreamFileForWrite(getName(), "wav", getExt()));
            wavWriter.writeHeader("Recorded with Wowza");
        } catch (IOException e) {
            WMSLoggerFactory.getLogger(null).info(e.getMessage(), e);
        }
    }
    public void stopPublishing() {
        super.stopPublishing();
        try {
            spxWriter.close();
            wavWriter.close();
        } catch (IOException e) {
            WMSLoggerFactory.getLogger(null).info(e.getMessage(), e);
        }
        WMSLoggerFactory.getLogger(null).info("MediaStreamAudioRecord: stopPublishing");
    }
    public void addAudioData(byte[] data, int offset, int size) {
        super.addAudioData(data, offset, size);
        if (this.audioBuffer == null) {
            this.audioBuffer = ByteBuffer.allocate(this.getAudioSize());
        }
        this.audioBytes += size;
        this.audioBuffer.put(data, offset, size);
        if (this.audioBytes == this.getAudioSize()) {
            try {
                // write Speex data
                spxWriter.writePacket(audioBuffer.array(), audioBuffer.arrayOffset() + 1, audioBytes - 1);
                // decode and write Wave data
                SpeexDecoder speexDecoder = new SpeexDecoder();
                speexDecoder.init(1, 16000, 1, false);
                speexDecoder.processData(audioBuffer.array(), audioBuffer.arrayOffset() + 1, audioBytes - 1);
                byte[] decoded = new byte[speexDecoder.getProcessedDataByteSize()];
                int decsize = speexDecoder.getProcessedData(decoded, 0);
                if (decsize > 0) {
                    wavWriter.writePacket(decoded, 0, decsize);
                }
            } catch (IOException e) {
                WMSLoggerFactory.getLogger(null).info(e.getMessage(), e);
            }
            this.audioBytes = 0;
            this.audioBuffer = null;
        }
    }
}