Android中的PCM数据字节到Vorbis

时间:2014-04-16 19:03:14

标签: java android audio encode oggvorbis

我正在尝试将PCM数据字节转换为OGG格式。我正在使用xiph Vorbis Encoder类来执行此操作。我的代码生成OGG文件但是当我播放它时,没有这样的声音只是sshhh。 请参阅此处https://www.dropbox.com/s/2m3fwujjm88s66a/demo.ogg

代码

public AudioRecord findAudioRecord() {
    for (int rate : mSampleRates) {
        for (short audioFormat : new short[]{AudioFormat.ENCODING_PCM_16BIT}) {
            for (short channelConfig : new short[]{AudioFormat.CHANNEL_IN_STEREO}) {
                try {
                    Log.d(LOG_TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
                            + channelConfig);
                    bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);

                    if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
                        // check if we can instantiate and have a success
                        recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
                        if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
                            return recorder;
                    }
                } catch (Exception e) {
                    Log.e(LOG_TAG, rate + "Exception, keep trying.", e);
                }
            }
        }
    }
    return null;
}

// convert short to byte
private byte[] short2byte(short[] sData) {
    int shortArrsize = sData.length;
    byte[] bytes = new byte[shortArrsize * 2];
    for (int i = 0; i < shortArrsize; i++) {
        bytes[i * 2] = (byte) (sData[i] & 0x00FF);
        bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
        sData[i] = 0;
    }
    return bytes;

}


private void writeAudioDataToFile() {
    // Write the output audio in byte
    short sData[] = new short[bufferSize / 2];

    try {
        vorbisFileOutputStream = new VorbisFileOutputStream(
                "/sdcard/demo.ogg");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
            vorbisFileOutputStream);
    dataOutputStream = new DataOutputStream(bufferedOutputStream);

    while (isRecording) {
        // gets the voice output from microphone to byte format
        recorder.read(sData, 0, bufferSize / 2);
        System.out.println("Short writing to file" + sData.toString());
        try {
            // writes the data to file from buffer stores the voice buffer
            dataOutputStream.write(short2byte(sData));
            //vorbisFileOutputStream.write(short2byte(sData));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

VorbisFileOutputStream.java

public class VorbisFileOutputStream extends AudioOutputStream {
    // The index into native memory where the ogg stream info is stored.
    private final int oggStreamIdx;
    private VorbisInfo info;
    private static final int VORBIS_BLOCK_SIZE = 1024;

    static {
        System.loadLibrary("ogg");
        System.loadLibrary("vorbis");
        System.loadLibrary("vorbis-stream");
    }

    public VorbisFileOutputStream (String fname, VorbisInfo s) throws IOException {
        info = s;
        oggStreamIdx = this.create(fname, s);
    }
    public VorbisFileOutputStream (String fname) throws IOException {
        oggStreamIdx = this.create(fname, new VorbisInfo());
    }

    @Override
    public void close() throws IOException {
        this.closeStreamIdx(this.oggStreamIdx);
    }

    /**
     * Write PCM data to ogg.  This assumes that you pass your streams in interleaved.
     * @param buffer
     * @param offset
     * @param length
     * @return
     * @throws IOException
     */
    @Override
    public void write(final short [] buffer, int offset, int length) throws IOException {
        this.writeStreamIdx(this.oggStreamIdx, buffer, offset, length);
    }

    private native int writeStreamIdx(int idx, short [] pcmdata, int offset, int size) throws IOException;
    private native void closeStreamIdx(int idx) throws IOException;
    private native int create(String path, VorbisInfo s) throws IOException;
    @Override
    public int getSampleRate() {
        return info.sampleRate;
    }
}

0 个答案:

没有答案