mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 00:20:47 +01:00
Update mixing code
This commit is contained in:
parent
05119fdceb
commit
c99034cff8
@ -340,7 +340,7 @@ int main(int argc, char ** argv) {
|
||||
char outfilename_temp[PATH_LIMIT];
|
||||
|
||||
sample_t * buf = NULL;
|
||||
int channels;
|
||||
int channels, input_channels;
|
||||
int32_t len_samples;
|
||||
int32_t fade_samples;
|
||||
int i, j;
|
||||
@ -458,8 +458,19 @@ int main(int argc, char ** argv) {
|
||||
|
||||
/* last init */
|
||||
channels = vgmstream->channels;
|
||||
input_channels = vgmstream->channels;
|
||||
|
||||
buf = malloc(BUFFER_SAMPLES * sizeof(sample_t) * channels);
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
/* enable after all config but before outbuf */
|
||||
{
|
||||
vgmstream_enable_mixing(vgmstream, BUFFER_SAMPLES);
|
||||
|
||||
channels = vgmstream->output_channels;
|
||||
input_channels = vgmstream->input_channels;
|
||||
}
|
||||
#endif
|
||||
|
||||
buf = malloc(BUFFER_SAMPLES * sizeof(sample_t) * input_channels);
|
||||
if (!buf) {
|
||||
fprintf(stderr,"failed allocating output buffer\n");
|
||||
goto fail;
|
||||
|
@ -569,6 +569,16 @@ static VGMSTREAM * init_vgmstream_internal(STREAMFILE *streamFile) {
|
||||
}
|
||||
|
||||
void setup_vgmstream(VGMSTREAM * vgmstream) {
|
||||
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
/* fill default config to simplify external code (mixing off will always happen
|
||||
* initially, and if they contain values it means mixing must be enabled) */
|
||||
if (!vgmstream->mixing_on || vgmstream->input_channels <= 0)
|
||||
vgmstream->input_channels = vgmstream->channels;
|
||||
if (!vgmstream->mixing_on || vgmstream->output_channels <= 0)
|
||||
vgmstream->output_channels = vgmstream->channels;
|
||||
#endif
|
||||
|
||||
/* save start things so we can restart when seeking */
|
||||
memcpy(vgmstream->start_ch, vgmstream->ch, sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
|
||||
memcpy(vgmstream->start_vgmstream, vgmstream, sizeof(VGMSTREAM));
|
||||
@ -747,9 +757,9 @@ VGMSTREAM * allocate_vgmstream(int channel_count, int loop_flag) {
|
||||
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
/* fixed arrays, for now */
|
||||
vgmstream->mixing_size = 64;
|
||||
vgmstream->stream_name_size = STREAM_NAME_SIZE;
|
||||
vgmstream->mixing_size = VGMSTREAM_MAX_MIXING;
|
||||
#endif
|
||||
//vgmstream->stream_name_size = STREAM_NAME_SIZE;
|
||||
return vgmstream;
|
||||
fail:
|
||||
if (vgmstream) {
|
||||
@ -980,6 +990,9 @@ void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target) {
|
||||
vgmstream_set_loop_target(data->layers[i], loop_target);
|
||||
}
|
||||
}
|
||||
|
||||
/* notify of new initial state */
|
||||
setup_vgmstream(vgmstream);
|
||||
}
|
||||
|
||||
|
||||
@ -1042,7 +1055,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifndef VGMSTREAM_MIXING
|
||||
/* swap channels if set, to create custom channel mappings */
|
||||
if (vgmstream->channel_mappings_on) {
|
||||
int ch_from,ch_to,s;
|
||||
@ -1075,6 +1088,11 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
mix_vgmstream(buffer, sample_count, vgmstream);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get the number of samples of a single frame (smallest self-contained sample group, 1/N channels) */
|
||||
@ -2529,7 +2547,7 @@ static void try_dual_file_stereo(VGMSTREAM * opened_vgmstream, STREAMFILE *strea
|
||||
}
|
||||
|
||||
/* check these even if there is no loop, because they should then be zero in both
|
||||
* Homura PS2 right channel doesn't have loop points so it's ignored */
|
||||
* (Homura PS2 right channel doesn't have loop points so this check is ignored) */
|
||||
if (new_vgmstream->meta_type != meta_PS2_SMPL &&
|
||||
!(new_vgmstream->loop_flag == opened_vgmstream->loop_flag &&
|
||||
new_vgmstream->loop_start_sample== opened_vgmstream->loop_start_sample &&
|
||||
|
@ -9,6 +9,9 @@
|
||||
enum { PATH_LIMIT = 32768 };
|
||||
enum { STREAM_NAME_SIZE = 255 };
|
||||
enum { VGMSTREAM_MAX_CHANNELS = 64 };
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
enum { VGMSTREAM_MAX_MIXING = 64 };
|
||||
#endif
|
||||
|
||||
#include "streamfile.h"
|
||||
|
||||
@ -731,20 +734,28 @@ typedef enum {
|
||||
MIX_ADD,
|
||||
MIX_ADD_VOLUME,
|
||||
MIX_VOLUME,
|
||||
MIX_CROSSFADE,
|
||||
MIX_LIMIT,
|
||||
MIX_DOWNMIX,
|
||||
MIX_DOWNMIX_REST,
|
||||
MIX_UPMIX
|
||||
MIX_UPMIX,
|
||||
MIX_FADE
|
||||
} mix_command_t;
|
||||
|
||||
typedef struct {
|
||||
mix_command_t command;
|
||||
int ch_a;
|
||||
int ch_b;
|
||||
float vol_a;
|
||||
float vol_b;
|
||||
float pos_a;
|
||||
float pos_b;
|
||||
/* common */
|
||||
int ch_dst;
|
||||
int ch_src;
|
||||
float vol;
|
||||
|
||||
/* fade envelope */
|
||||
float vol_start; /* volume from pre to start */
|
||||
float vol_end; /* volume from end to post */
|
||||
char shape; /* curve type */
|
||||
float time_pre; /* position before curve where vol_str applies (-1 = beginning) */
|
||||
float time_start; /* curve start position where vol changes from src to dst */
|
||||
float time_end; /* curve end position where vol changes from src to dst */
|
||||
float time_post; /* position after curve where vol_dst applies (-1 = end) */
|
||||
} mix_config_data;
|
||||
#endif
|
||||
|
||||
@ -823,15 +834,19 @@ typedef struct {
|
||||
|
||||
/* other config */
|
||||
int allow_dual_stereo; /* search for dual stereo (file_L.ext + file_R.ext = single stereo file) */
|
||||
#ifndef VGMSTREAM_MIXING
|
||||
uint32_t channel_mask; /* to silence crossfading subsongs/layers */
|
||||
int channel_mappings_on; /* channel mappings are active */
|
||||
int channel_mappings[32]; /* swap channel "i" with "[i]" */
|
||||
#endif
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
int output_channels; /* resulting channels after mixing (may be ignored if plugin doesn't support it) */
|
||||
/* may be ignored if plugin doesn't support it, but fields will be always set to simplify plugin's code */
|
||||
int input_channels; /* starting channels before mixing (outbuf must be this big) */
|
||||
int output_channels; /* resulting channels after mixing */
|
||||
int mixing_on; /* mixing allowed */
|
||||
int mixing_count; /* mixing number */
|
||||
mix_config_data mixing[64]; /* applies transformation to output samples (could be alloc'ed but to simplify...) */
|
||||
size_t mixing_size; /* mixing max */
|
||||
mix_config_data mixing_chain[VGMSTREAM_MAX_MIXING]; /* effects to apply (could be alloc'ed but to simplify...) */
|
||||
#endif
|
||||
/* config requests, players must read and honor these values */
|
||||
/* (ideally internally would work as a player, but for now player must do it manually) */
|
||||
@ -1317,6 +1332,15 @@ VGMSTREAM * allocate_vgmstream(int channel_count, int looped);
|
||||
/* Prepare the VGMSTREAM's initial state once parsed and ready, but before playing. */
|
||||
void setup_vgmstream(VGMSTREAM * vgmstream);
|
||||
|
||||
#ifdef VGMSTREAM_MIXING
|
||||
/* Applies mixing commands to the vgmstream to the sample buffer.
|
||||
* Mixing must be enabled and outbuf must be big enough for output_channels*samples_to_do big. */
|
||||
void mix_vgmstream(sample_t *outbuf, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
||||
/* Add a new internal mix. Always use this as it validates mixes. */
|
||||
void vgmstream_add_mixing(VGMSTREAM* vgmstream, mix_config_data mix);
|
||||
#endif
|
||||
|
||||
/* Get the number of samples of a single frame (smallest self-contained sample group, 1/N channels) */
|
||||
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream);
|
||||
/* Get the number of bytes of a single frame (smallest self-contained byte group, 1/N channels) */
|
||||
|
Loading…
Reference in New Issue
Block a user