mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 16:30:54 +01:00
Improve seeking speed in layered/segmented layout in some cases
This commit is contained in:
parent
2f516d4e29
commit
3b80e4c813
@ -76,6 +76,18 @@ decode_fail:
|
||||
}
|
||||
|
||||
|
||||
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample) {
|
||||
int layer;
|
||||
layered_layout_data* data = vgmstream->layout_data;
|
||||
|
||||
for (layer = 0; layer < data->layer_count; layer++) {
|
||||
seek_vgmstream(data->layers[layer], seek_sample);
|
||||
}
|
||||
|
||||
vgmstream->current_sample = seek_sample;
|
||||
vgmstream->samples_into_block = seek_sample;
|
||||
}
|
||||
|
||||
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample) {
|
||||
int layer;
|
||||
layered_layout_data* data = vgmstream->layout_data;
|
||||
|
@ -59,7 +59,8 @@ segmented_layout_data* init_layout_segmented(int segment_count);
|
||||
int setup_layout_segmented(segmented_layout_data* data);
|
||||
void free_layout_segmented(segmented_layout_data* data);
|
||||
void reset_layout_segmented(segmented_layout_data* data);
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM *allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment);
|
||||
|
||||
void render_vgmstream_layered(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
@ -67,7 +68,8 @@ layered_layout_data* init_layout_layered(int layer_count);
|
||||
int setup_layout_layered(layered_layout_data* data);
|
||||
void free_layout_layered(layered_layout_data* data);
|
||||
void reset_layout_layered(layered_layout_data* data);
|
||||
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM *allocate_layered_vgmstream(layered_layout_data* data);
|
||||
|
||||
#endif
|
||||
|
@ -115,7 +115,7 @@ static inline void copy_samples(sample_t* outbuf, segmented_layout_data* data, i
|
||||
}
|
||||
|
||||
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
|
||||
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample) {
|
||||
int segment, total_samples;
|
||||
segmented_layout_data* data = vgmstream->layout_data;
|
||||
|
||||
@ -124,13 +124,13 @@ void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
|
||||
while (total_samples < vgmstream->num_samples) {
|
||||
int32_t segment_samples = vgmstream_get_samples(data->segments[segment]);
|
||||
|
||||
/* find if loop falls within segment's samples */
|
||||
if (loop_sample >= total_samples && loop_sample < total_samples + segment_samples) {
|
||||
int32_t loop_relative = loop_sample - total_samples;
|
||||
/* find if sample falls within segment's samples */
|
||||
if (seek_sample >= total_samples && seek_sample < total_samples + segment_samples) {
|
||||
int32_t seek_relative = seek_sample - total_samples;
|
||||
|
||||
seek_vgmstream(data->segments[segment], loop_relative);
|
||||
seek_vgmstream(data->segments[segment], seek_relative);
|
||||
data->current_segment = segment;
|
||||
vgmstream->samples_into_block = loop_relative;
|
||||
vgmstream->samples_into_block = seek_relative;
|
||||
break;
|
||||
}
|
||||
total_samples += segment_samples;
|
||||
@ -138,10 +138,14 @@ void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
|
||||
}
|
||||
|
||||
if (segment == data->segment_count) {
|
||||
VGM_LOG("SEGMENTED: can't find loop segment\n");
|
||||
VGM_LOG("SEGMENTED: can't find seek segment\n");
|
||||
}
|
||||
}
|
||||
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
|
||||
loop_layout_segmented(vgmstream, loop_sample);
|
||||
}
|
||||
|
||||
|
||||
segmented_layout_data* init_layout_segmented(int segment_count) {
|
||||
segmented_layout_data* data = NULL;
|
||||
|
33
src/render.c
33
src/render.c
@ -548,6 +548,33 @@ void seek_vgmstream(VGMSTREAM* vgmstream, int32_t seek_sample) {
|
||||
int is_looped = vgmstream->loop_flag || vgmstream->loop_target > 0; /* loop target disabled loop flag during decode */
|
||||
|
||||
|
||||
/* cleanup */
|
||||
if (seek_sample < 0)
|
||||
seek_sample = 0;
|
||||
/* play forever can seek past max */
|
||||
if (vgmstream->config_enabled && seek_sample > ps->play_duration && !play_forever)
|
||||
seek_sample = ps->play_duration;
|
||||
|
||||
|
||||
/* optimize as layouts can seek faster internally */
|
||||
if (vgmstream->layout_type == layout_segmented) {
|
||||
seek_layout_segmented(vgmstream, seek_sample);
|
||||
|
||||
if (vgmstream->config_enabled) {
|
||||
vgmstream->pstate.play_position = seek_sample;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (vgmstream->layout_type == layout_layered) {
|
||||
seek_layout_layered(vgmstream, seek_sample);
|
||||
|
||||
if (vgmstream->config_enabled) {
|
||||
vgmstream->pstate.play_position = seek_sample;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* will decode and loop until seek sample, but slower */
|
||||
//todo apply same loop logic as below, or pretend we have play_forever + settings?
|
||||
if (!vgmstream->config_enabled) {
|
||||
@ -580,12 +607,6 @@ void seek_vgmstream(VGMSTREAM* vgmstream, int32_t seek_sample) {
|
||||
* | pad-begin | body-begin | body-loop0 | body-loop1 | body-loop2 | fade | pad-end + beyond)
|
||||
* 0 5s (-3s) 25s 95s 165s 235s 245s Ns
|
||||
*/
|
||||
|
||||
if (seek_sample < 0)
|
||||
seek_sample = 0;
|
||||
if (seek_sample > ps->play_duration && !play_forever) /* play forever can seek to any loop */
|
||||
seek_sample = ps->play_duration;
|
||||
|
||||
//;VGM_LOG("SEEK: seek sample=%i, is_looped=%i\n", seek_sample, is_looped);
|
||||
|
||||
/* start/pad-begin: consume pad samples */
|
||||
|
Loading…
Reference in New Issue
Block a user