我有音频样本; 如何使用SDL正确播放它们?

我正在为libretro核心编写一个非常简单的前端,我正在攻击音频部分,最难(我以前从来没有处理过与声音有关的任何事情,所以很可能我完全错误)。

它的工作方式,libretro核心定期调用一个函数原型,因为我必须自己实现:

typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t count);

data参数是隔行立体声数据阵列( { Left, Right, Left, ...}count是样本的数目(以使阵列元素计数实际计数* 2)。

以下是我目前对这些数据所做的工作:

  • 当libretro核心发送样品时
  • 我只是将它们连接到一个音频缓冲区
  • 当SDL正在调用我的音频回调方法时,
  • 我尽可能多地从音频缓冲区复制到流缓冲区
  • 如果没有足够的数据可用,我用0填充流缓冲区的其余部分
  • 如果我的缓冲区有比请求更多的数据,我只是删除我刚刚播放的内容并保留其余部分
  • 但是,我得到的是不正确的。 尽管有些可辨认,但声音是乱码和充满了噪音。 我不确定我可能会错过什么:似乎RetroArch前端(libretro内核的官方前端)正在进行某种重采样,但我不知道它是什么。 是否需要重采样? 我可以从这个问题来吗?

    以下是我的完整代码,部分复制如下:

    static int16_t * g_audio_samples = NULL;
    static size_t g_audio_sample_count = 0;
    
    static void audio_write( int16_t const * samples, size_t count )
    {
        SDL_LockAudio( );
    
        int16_t * previous_samples = g_audio_samples;
        size_t previous_count = g_audio_sample_count;
    
        g_audio_sample_count = previous_count + count;
        g_audio_samples = calloc( g_audio_sample_count * 2, sizeof( int16_t ) );
    
        for ( size_t index = 0; index < previous_count; ++ index )
            g_audio_samples[ index ] = previous_samples[ index ];
    
        for ( size_t index = 0; index < count; ++ index )
            g_audio_samples[ previous_count + index ] = samples[ index ];
    
        free( previous_samples );
    
        SDL_UnlockAudio( );
    }
    
    static void audio_callback( void * userdata, Uint8 * stream, int length )
    {
        int16_t * available_samples = g_audio_samples;
        size_t available_sample_count = g_audio_sample_count;
    
        size_t requested_sample_count = length / 2;
        size_t requested_byte_length = requested_sample_count * 2;
    
        size_t providen_sample_count = requested_sample_count < available_sample_count ? requested_sample_count : available_sample_count;
        size_t providen_byte_length = providen_sample_count * 2;
    
        memcpy( stream, available_samples, providen_byte_length );
        memset( stream + providen_byte_length, 0, requested_byte_length - providen_byte_length );
    
        g_audio_samples = NULL;
        g_audio_sample_count = 0;
    
        if ( providen_sample_count < available_sample_count )
            audio_write( available_samples + providen_sample_count, available_sample_count - providen_sample_count );
    
        free( available_samples );
    }
    
    size_t bridge_virtjs_audio_push_sample_batch( int16_t const * samples, size_t count )
    {
        audio_write( samples, count );
    
        return count;
    }
    
    链接地址: http://www.djcxy.com/p/33825.html

    上一篇: I've got audio samples; how to play them correctly with the SDL?

    下一篇: Problems with SDL Audio (No output)