使用JNI将ioquake3声音流传输到android,声音以其一半的速度播放

时间:2019-11-30 15:04:59

标签: android audio

我正在尝试在没有SDL的情况下将声音从quake3播放到android设备。 以下代码有效,但是声音以其一半的速度播放。

在Java文件中:

public void audio_thread() throws IOException
{
    int sampleRate = 22050;
    int audioSize = ( 2048 * 4 );

    ByteBuffer audioBuffer = ByteBuffer.allocateDirect(audioSize);
    byte[] audioData = new byte[audioSize];       

    int bufferSize = AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);

    AudioTrack oTrack = new AudioTrack(AudioManager.USE_DEFAULT_STREAM_TYPE, sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);

    while (!stop_audio) {
        // call jni function from native code
        sQuake3PaintAudio( audioBuffer );

        audioBuffer.position(0);
        audioBuffer.get(audioData);

        // Write the byte array to the track
        oTrack.write(audioData, 0, audioData.length);
    }
    // Done writing to the track
    oTrack.stop();
}

使用本机代码:

static int dmapos = 0;

JNIEXPORT jint JNICALL Java_com_ioquake3_Quake3PaintAudio( JNIEnv* env, jobject thiz, jobject buf )
{
    extern int paint_audio (void *unused, void * stream, int len);
    void *stream;
    int len;

    stream = (*env)->GetDirectBufferAddress( env,  buf);
    len = (*env)->GetDirectBufferCapacity( env,  buf);
    return paint_audio ( NULL, stream, len );
}

int paint_audio (void *unused, void * stream, int len)
{
    if (!snd_inited) return 0;
    dma.buffer = stream;
    dmapos += len / (dma.samplebits / 4);
    return len;
}

我更改了ioquake3的SNDDMA_Init()函数:

qboolean SNDDMA_Init(void)
{
    // most of the wav files are 16 bits, 22050 Hz, mono
    dmapos = 0;
    dma.channels = 2;
    dma.samples = 2048 * dma.channels; // I have tried with 1024 * 2 but application crashed
    dma.fullsamples = dma.samples / dma.channels;
    dma.submission_chunk = 1;
    dma.samplebits = 16;
    dma.speed = 22050; // I've tried 44100 hz but got chipmunks effect
    dma.buffer = NULL;
    snd_inited = 1;
    return qtrue;
}

ioquake3中的所有其他内容均未更改。我尝试了不同的价值观而没有成功,请您帮我找出我的错误吗?

0 个答案:

没有答案