implement repeat in libxm

This commit is contained in:
veclavtalica 2024-07-08 18:00:38 +03:00
parent c539473021
commit c07aa3c9a8
2 changed files with 34 additions and 16 deletions

View File

@ -130,6 +130,8 @@ static union audio_context init_audio_context(const char *path, t_audio_file_typ
break; break;
} }
xm_set_max_loop_count(handle, 1);
return (union audio_context) { return (union audio_context) {
.xm = { .handle = handle } .xm = { .handle = handle }
}; };
@ -250,19 +252,21 @@ static void audio_sample_and_mixin_channel(const struct audio_channel *channel,
/* handle end of file */ /* handle end of file */
if (samples_per_channel == 0) { if (samples_per_channel == 0) {
if (channel->args.repeat) if (channel->args.repeat) {
/* seek to start and try sampling some more */ /* seek to start and try sampling some more */
stb_vorbis_seek_start(channel->context.vorbis.handle); stb_vorbis_seek_start(channel->context.vorbis.handle);
else continue;
} else
/* leave silence */ /* leave silence */
break; break;
} }
/* panning and mixing */ /* panning and mixing */
audio_mixin_streams(channel, &stream[i * sizeof(int16_t)], buffer, audio_mixin_streams(channel,
samples_per_channel * ctx.audio_stream_channel_count); &stream[i * sizeof(int16_t)], buffer,
samples_per_channel * 2);
i += samples_per_channel * ctx.audio_stream_channel_count; i += samples_per_channel * 2;
} }
break; break;
@ -273,19 +277,32 @@ static void audio_sample_and_mixin_channel(const struct audio_channel *channel,
const int n_frames = (stream_frames - i) > float_buffer_frames ? const int n_frames = (stream_frames - i) > float_buffer_frames ?
float_buffer_frames : stream_frames - i; float_buffer_frames : stream_frames - i;
/* TODO: make it report generated frame count and stop right before looping */ const int samples_per_channel = xm_generate_samples(channel->context.xm.handle,
xm_generate_samples(channel->context.xm.handle, (float *)buffer, n_frames / 2); (float *)buffer,
n_frames / 2);
/* convert floats to int16_t */ /* handle end of file */
for (int p = 0; p < n_frames; ++p) { if (samples_per_channel == 0) {
const int16_t value = (int16_t)(((float *)buffer)[p] * 32768.0f); if (channel->args.repeat) {
((int16_t *)buffer)[p] = value; /* seek to start and try sampling some more */
xm_restart(channel->context.xm.handle);
continue;
} else
/* leave silence */
break;
} }
/* panning and mixing */ /* convert floats to int16_t */
audio_mixin_streams(channel, &stream[i * sizeof(int16_t)], buffer, n_frames); for (int p = 0; p < samples_per_channel * 2; ++p)
((int16_t *)buffer)[p] = (int16_t)(((float *)buffer)[p] * 32768.0f);
i += n_frames; /* panning and mixing */
audio_mixin_streams(channel,
&stream[i * sizeof(int16_t)],
buffer,
samples_per_channel * 2);
i += samples_per_channel * 2;
} }
break; break;

View File

@ -30,9 +30,10 @@ struct scene *ingame_scene(struct state *state) {
new_scene->world = world_create(); new_scene->world = world_create();
new_scene->player = player_create(new_scene->world); new_scene->player = player_create(new_scene->world);
play_audio_ex("music/test.ogg", "soundtrack", (t_play_audio_args){ play_audio_ex("music/repeat-test.xm", "soundtrack", (t_play_audio_args){
.volume = 0.8f, .volume = 0.8f,
.panning = -0.5f .panning = -0.5f,
.repeat = true,
}); });
return (struct scene *)new_scene; return (struct scene *)new_scene;