Add audio batch callback.

This commit is contained in:
Themaister 2012-03-27 22:24:46 +02:00
parent 29f1138ec6
commit 104c92fa5d
3 changed files with 38 additions and 0 deletions

View File

@ -289,6 +289,8 @@ void dylib_close(dylib_t lib)
}
#endif
unsigned audio_sample_batch(const int16_t *, unsigned);
#if defined(NEED_DYNAMIC) || defined(SSNES_CONSOLE)
static bool environment_cb(unsigned cmd, void *data)
{
@ -410,6 +412,11 @@ static bool environment_cb(unsigned cmd, void *data)
break;
}
case SNES_ENVIRONMENT_GET_AUDIO_BATCH_CB:
SSNES_LOG("Environ GET_AUDIO_BATCH_CB\n");
*(snes_audio_sample_batch_t*)data = audio_sample_batch;
break;
default:
SSNES_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
return false;

View File

@ -126,6 +126,11 @@ extern "C" {
//
#define SNES_ENVIRONMENT_SET_MESSAGE 12 // const struct snes_message * --
// Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'.
//
#define SNES_ENVIRONMENT_GET_AUDIO_BATCH_CB 13 // snes_audio_sample_batch_t * --
// Retrieves callback to a more optimized audio callback.
struct snes_message
{
@ -164,6 +169,10 @@ void snes_set_environment(snes_environment_t);
typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height);
typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
// Performance extension. Retrieved from environ callback.
typedef unsigned (*snes_audio_sample_batch_t)(const int16_t *data, unsigned frames);
typedef void (*snes_input_poll_t)(void);
typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id);

22
ssnes.c
View File

@ -390,6 +390,28 @@ static void audio_sample(uint16_t left, uint16_t right)
g_extern.audio_data.data_ptr = 0;
}
// Non-standard, alternative callback better suited for systems that process audio in batch.
// Avoids tons of calls to audio_sample() ...
unsigned audio_sample_batch(const int16_t *data, unsigned frames)
{
if (frames > (AUDIO_CHUNK_SIZE_NONBLOCKING >> 1))
frames = AUDIO_CHUNK_SIZE_NONBLOCKING >> 1;
memcpy(g_extern.audio_data.conv_outsamples,
data, (frames << 1) * sizeof(int16_t));
g_extern.audio_data.data_ptr = frames << 1;
if (g_extern.audio_data.data_ptr >= g_extern.audio_data.chunk_size)
{
g_extern.audio_active = audio_flush(g_extern.audio_data.conv_outsamples,
g_extern.audio_data.data_ptr) && g_extern.audio_active;
g_extern.audio_data.data_ptr = 0;
}
return frames;
}
static void input_poll(void)
{
driver.input->poll(driver.input_data);