ibxm: update to 20191214
- Fix music playback (sample skipping) - Add more platforms - Fix Mr. Boom music
This commit is contained in:
parent
175205c1e6
commit
8017ecd2b8
|
@ -35,6 +35,7 @@ HAVE_STATIC_AUDIO_FILTERS = 1
|
||||||
HAVE_STB_FONT = 1
|
HAVE_STB_FONT = 1
|
||||||
HAVE_CONFIGFILE = 1
|
HAVE_CONFIGFILE = 1
|
||||||
HAVE_CHEATS = 1
|
HAVE_CHEATS = 1
|
||||||
|
HAVE_IBXM = 1
|
||||||
|
|
||||||
MEMORY = 134217728
|
MEMORY = 134217728
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ HAVE_STB_FONT = 1
|
||||||
HAVE_CHEEVOS = 1
|
HAVE_CHEEVOS = 1
|
||||||
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
|
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
|
||||||
HAVE_STB_VORBIS = 1
|
HAVE_STB_VORBIS = 1
|
||||||
|
HAVE_IBXM = 1
|
||||||
|
|
||||||
# RetroArch libnx useful flags
|
# RetroArch libnx useful flags
|
||||||
HAVE_THREADS = 1
|
HAVE_THREADS = 1
|
||||||
|
|
|
@ -40,6 +40,7 @@ else
|
||||||
HAVE_DYNAMIC = 1
|
HAVE_DYNAMIC = 1
|
||||||
HAVE_PATCH = 1
|
HAVE_PATCH = 1
|
||||||
HAVE_CHEATS = 1
|
HAVE_CHEATS = 1
|
||||||
|
HAVE_IBXM = 1
|
||||||
|
|
||||||
include Makefile.common
|
include Makefile.common
|
||||||
CFLAGS += $(DEF_FLAGS)
|
CFLAGS += $(DEF_FLAGS)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Micromod (c)2017 mumart@gmail.com
|
Micromod (c)2019 mumart@gmail.com
|
||||||
|
|
||||||
A good-quality player library for the ProTracker MOD music format
|
A good-quality player library for the ProTracker MOD music format
|
||||||
for Javascript (HTML5 Web Audio), Java, ANSI C (SDL) and Pascal (SDL).
|
for Javascript (HTML5 Web Audio), Java, ANSI C (SDL) and Pascal (SDL).
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "ibxm.h"
|
#include "ibxm.h"
|
||||||
|
|
||||||
const char *IBXM_VERSION = "ibxm/ac mod/xm/s3m replay 20170901 (c)mumart@gmail.com";
|
const char *IBXM_VERSION = "ibxm/ac mod/xm/s3m replay 20191214 (c)mumart@gmail.com";
|
||||||
|
|
||||||
static const int FP_SHIFT = 15, FP_ONE = 32768, FP_MASK = 32767;
|
static const int FP_SHIFT = 15, FP_ONE = 32768, FP_MASK = 32767;
|
||||||
|
|
||||||
|
@ -787,8 +787,14 @@ static struct module* module_load_mod( struct data *data, char *message ) {
|
||||||
if( param == 0 && ( effect == 5 || effect == 6 ) ) {
|
if( param == 0 && ( effect == 5 || effect == 6 ) ) {
|
||||||
effect -= 2;
|
effect -= 2;
|
||||||
}
|
}
|
||||||
if( effect == 8 && module->num_channels == 4 ) {
|
if( effect == 8 ) {
|
||||||
|
if( module->num_channels == 4 ) {
|
||||||
effect = param = 0;
|
effect = param = 0;
|
||||||
|
} else if( param > 128 ) {
|
||||||
|
param = 128;
|
||||||
|
} else {
|
||||||
|
param = ( param * 255 ) >> 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pattern_data[ pat_data_idx + 3 ] = effect;
|
pattern_data[ pat_data_idx + 3 ] = effect;
|
||||||
pattern_data[ pat_data_idx + 4 ] = param;
|
pattern_data[ pat_data_idx + 4 ] = param;
|
||||||
|
@ -851,7 +857,7 @@ static struct module* module_load_mod( struct data *data, char *message ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate and initialize a module from the specified data, returns NULL on error.
|
/* Allocate and initialize a module from the specified data, returns NULL on error.
|
||||||
Message should point to a 64-character buffer to receive error messages. */
|
Message must point to a 64-character buffer to receive error messages. */
|
||||||
struct module* module_load( struct data *data, char *message ) {
|
struct module* module_load( struct data *data, char *message ) {
|
||||||
char ascii[ 16 ];
|
char ascii[ 16 ];
|
||||||
struct module* module;
|
struct module* module;
|
||||||
|
@ -1427,7 +1433,7 @@ static void channel_row( struct channel *channel, struct note *note ) {
|
||||||
channel_tremolo( channel );
|
channel_tremolo( channel );
|
||||||
break;
|
break;
|
||||||
case 0x08: /* Set Panning.*/
|
case 0x08: /* Set Panning.*/
|
||||||
channel->panning = ( channel->note.param < 128 ) ? ( channel->note.param << 1 ) : 255;
|
channel->panning = channel->note.param & 0xFF;
|
||||||
break;
|
break;
|
||||||
case 0x0A: case 0x84: /* Vol Slide. */
|
case 0x0A: case 0x84: /* Vol Slide. */
|
||||||
if( channel->note.param > 0 ) {
|
if( channel->note.param > 0 ) {
|
||||||
|
@ -1901,8 +1907,9 @@ static void downsample( int *buf, int count ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates audio and returns the number of stereo samples written into mix_buf. */
|
/* Generates audio and returns the number of stereo samples written into mix_buf.
|
||||||
int replay_get_audio( struct replay *replay, int *mix_buf ) {
|
Individual channels may be excluded using the mute bitmask. */
|
||||||
|
int replay_get_audio( struct replay *replay, int *mix_buf, int mute ) {
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
int idx, num_channels, tick_len = calculate_tick_len( replay->tempo, replay->sample_rate );
|
int idx, num_channels, tick_len = calculate_tick_len( replay->tempo, replay->sample_rate );
|
||||||
/* Clear output buffer. */
|
/* Clear output buffer. */
|
||||||
|
@ -1911,12 +1918,25 @@ int replay_get_audio( struct replay *replay, int *mix_buf ) {
|
||||||
num_channels = replay->module->num_channels;
|
num_channels = replay->module->num_channels;
|
||||||
for( idx = 0; idx < num_channels; idx++ ) {
|
for( idx = 0; idx < num_channels; idx++ ) {
|
||||||
channel = &replay->channels[ idx ];
|
channel = &replay->channels[ idx ];
|
||||||
|
if( !( mute & 1 ) ) {
|
||||||
channel_resample( channel, mix_buf, 0, ( tick_len + 65 ) * 2,
|
channel_resample( channel, mix_buf, 0, ( tick_len + 65 ) * 2,
|
||||||
replay->sample_rate * 2, replay->interpolation );
|
replay->sample_rate * 2, replay->interpolation );
|
||||||
|
}
|
||||||
channel_update_sample_idx( channel, tick_len * 2, replay->sample_rate * 2 );
|
channel_update_sample_idx( channel, tick_len * 2, replay->sample_rate * 2 );
|
||||||
|
mute >>= 1;
|
||||||
}
|
}
|
||||||
downsample( mix_buf, tick_len + 64 );
|
downsample( mix_buf, tick_len + 64 );
|
||||||
replay_volume_ramp( replay, mix_buf, tick_len );
|
replay_volume_ramp( replay, mix_buf, tick_len );
|
||||||
replay_tick( replay );
|
replay_tick( replay );
|
||||||
return tick_len;
|
return tick_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the currently playing pattern in the sequence.*/
|
||||||
|
int replay_get_sequence_pos( struct replay *replay ) {
|
||||||
|
return replay->seq_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the currently playing row in the pattern. */
|
||||||
|
int replay_get_row( struct replay *replay ) {
|
||||||
|
return replay->row;
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct module {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Allocate and initialize a module from the specified data, returns NULL on error.
|
/* Allocate and initialize a module from the specified data, returns NULL on error.
|
||||||
Message should point to a 64-character buffer to receive error messages. */
|
Message must point to a 64-character buffer to receive error messages. */
|
||||||
struct module* module_load( struct data *data, char *message );
|
struct module* module_load( struct data *data, char *message );
|
||||||
/* Deallocate the specified module. */
|
/* Deallocate the specified module. */
|
||||||
void dispose_module( struct module *module );
|
void dispose_module( struct module *module );
|
||||||
|
@ -63,8 +63,13 @@ int replay_calculate_duration( struct replay *replay );
|
||||||
int replay_seek( struct replay *replay, int sample_pos );
|
int replay_seek( struct replay *replay, int sample_pos );
|
||||||
/* Set the pattern in the sequence to play. The tempo is reset to the default. */
|
/* Set the pattern in the sequence to play. The tempo is reset to the default. */
|
||||||
void replay_set_sequence_pos( struct replay *replay, int pos );
|
void replay_set_sequence_pos( struct replay *replay, int pos );
|
||||||
/* Generates audio and returns the number of stereo samples written into mix_buf. */
|
/* Generates audio and returns the number of stereo samples written into mix_buf.
|
||||||
int replay_get_audio( struct replay *replay, int *mix_buf );
|
Individual channels may be excluded using the mute bitmask. */
|
||||||
|
int replay_get_audio( struct replay *replay, int *mix_buf, int mute );
|
||||||
|
/* Returns the currently playing pattern in the sequence.*/
|
||||||
|
int replay_get_sequence_pos( struct replay *replay );
|
||||||
|
/* Returns the currently playing row in the pattern. */
|
||||||
|
int replay_get_row( struct replay *replay );
|
||||||
/* Returns the length of the output buffer required by replay_get_audio(). */
|
/* Returns the length of the output buffer required by replay_get_audio(). */
|
||||||
int calculate_mix_buf_len( int sample_rate );
|
int calculate_mix_buf_len( int sample_rate );
|
||||||
|
|
||||||
|
|
|
@ -996,13 +996,11 @@ static void audio_mixer_mix_mod(float* buffer, size_t num_frames,
|
||||||
unsigned buf_free = (unsigned)(num_frames * 2);
|
unsigned buf_free = (unsigned)(num_frames * 2);
|
||||||
int* pcm = NULL;
|
int* pcm = NULL;
|
||||||
|
|
||||||
if (voice->types.mod.position == voice->types.mod.samples)
|
if (voice->types.mod.samples == 0)
|
||||||
{
|
{
|
||||||
again:
|
again:
|
||||||
temp_samples = replay_get_audio(
|
temp_samples = replay_get_audio(
|
||||||
voice->types.mod.stream, voice->types.mod.buffer );
|
voice->types.mod.stream, voice->types.mod.buffer, 0 ) * 2;
|
||||||
|
|
||||||
temp_samples *= 2; /* stereo */
|
|
||||||
|
|
||||||
if (temp_samples == 0)
|
if (temp_samples == 0)
|
||||||
{
|
{
|
||||||
|
@ -1031,10 +1029,9 @@ again:
|
||||||
{
|
{
|
||||||
for (i = voice->types.mod.samples; i != 0; i--)
|
for (i = voice->types.mod.samples; i != 0; i--)
|
||||||
{
|
{
|
||||||
samplei = *pcm++ * volume;
|
samplef = ((float)(*pcm++) + 32768.0f) / 65535.0f;
|
||||||
samplef = (float)((int)samplei + 32768) / 65535.0f;
|
|
||||||
samplef = samplef * 2.0f - 1.0f;
|
samplef = samplef * 2.0f - 1.0f;
|
||||||
*buffer++ += samplef;
|
*buffer++ += samplef * volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_free -= voice->types.mod.samples;
|
buf_free -= voice->types.mod.samples;
|
||||||
|
@ -1043,10 +1040,9 @@ again:
|
||||||
|
|
||||||
for (i = buf_free; i != 0; --i )
|
for (i = buf_free; i != 0; --i )
|
||||||
{
|
{
|
||||||
samplei = *pcm++ * volume;
|
samplef = ((float)(*pcm++) + 32768.0f) / 65535.0f;
|
||||||
samplef = (float)((int)samplei + 32768) / 65535.0f;
|
|
||||||
samplef = samplef * 2.0f - 1.0f;
|
samplef = samplef * 2.0f - 1.0f;
|
||||||
*buffer++ += samplef;
|
*buffer++ += samplef * volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
voice->types.mod.position += buf_free;
|
voice->types.mod.position += buf_free;
|
||||||
|
|
Loading…
Reference in New Issue