mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
Merge pull request #5244 from rtissera/modsupport
Add MOD/S3M/XM support to audio mixer (libretro-common) through micromod/ibxm
This commit is contained in:
commit
d11b9e80b4
@ -1324,6 +1324,11 @@ ifeq ($(HAVE_RBMP), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/bmp/rbmp.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_IBXM), 1)
|
||||
DEFINES += -DHAVE_IBXM
|
||||
OBJ += $(DEPS_DIR)/ibxm/ibxm.o
|
||||
endif
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/bmp/rbmp_encode.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/json/jsonsax.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/json/jsonsax_full.o \
|
||||
|
@ -133,6 +133,7 @@ endif
|
||||
HAVE_RJPEG := 1
|
||||
HAVE_RBMP := 1
|
||||
HAVE_RTGA := 1
|
||||
HAVE_IBXM := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_ZLIB := 1
|
||||
WANT_ZLIB := 1
|
||||
|
@ -914,6 +914,11 @@ bool audio_driver_mixer_extension_supported(const char *ext)
|
||||
|
||||
#ifdef HAVE_STB_VORBIS
|
||||
string_list_append(str_list, "ogg", attr);
|
||||
#endif
|
||||
#ifdef HAVE_IBXM
|
||||
string_list_append(str_list, "mod", attr);
|
||||
string_list_append(str_list, "s3m", attr);
|
||||
string_list_append(str_list, "xm", attr);
|
||||
#endif
|
||||
string_list_append(str_list, "wav", attr);
|
||||
|
||||
@ -1008,6 +1013,9 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
case AUDIO_MIXER_TYPE_OGG:
|
||||
handle = audio_mixer_load_ogg(buf, (int32_t)params->bufsize);
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_MOD:
|
||||
handle = audio_mixer_load_mod(buf, (int32_t)params->bufsize);
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_NONE:
|
||||
free(buf);
|
||||
return false;
|
||||
|
21
deps/ibxm/README
vendored
Normal file
21
deps/ibxm/README
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
Micromod (c)2017 mumart@gmail.com
|
||||
|
||||
A good-quality player library for the ProTracker MOD music format
|
||||
for Javascript (HTML5 Web Audio), Java, ANSI C (SDL) and Pascal (SDL).
|
||||
|
||||
Also hosted here is IBXM, a player library for the ProTracker MOD,
|
||||
Scream Tracker 3 S3M, and FastTracker 2 XM music formats for Javascript
|
||||
(HTML5 Web Audio), Java and ANSI C.
|
||||
|
||||
The Java version of Micromod contains a powerful command-line tool for
|
||||
the creation of MOD files from textual MT files and WAV samples.
|
||||
There is some basic documentation built-in to the tool and some example
|
||||
MT files are contained in the songs directory. Some knowledge of the
|
||||
ProTracker MOD format, audio synthesis and "tracking" is assumed.
|
||||
|
||||
If you have any questions or feedback please feel free to
|
||||
contact me at the above email address!
|
||||
|
||||
Cheers,
|
||||
Martin
|
1922
deps/ibxm/ibxm.c
vendored
Normal file
1922
deps/ibxm/ibxm.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
71
deps/ibxm/ibxm.h
vendored
Normal file
71
deps/ibxm/ibxm.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
/* ibxm/ac mod/xm/s3m replay (c)mumart@gmail.com */
|
||||
|
||||
#ifndef __IBXM_H__
|
||||
#define __IBXM_H__
|
||||
|
||||
const char *IBXM_VERSION;
|
||||
|
||||
struct data {
|
||||
char *buffer;
|
||||
int length;
|
||||
};
|
||||
|
||||
struct sample {
|
||||
char name[ 32 ];
|
||||
int loop_start, loop_length;
|
||||
short volume, panning, rel_note, fine_tune, *data;
|
||||
};
|
||||
|
||||
struct envelope {
|
||||
char enabled, sustain, looped, num_points;
|
||||
short sustain_tick, loop_start_tick, loop_end_tick;
|
||||
short points_tick[ 16 ], points_ampl[ 16 ];
|
||||
};
|
||||
|
||||
struct instrument {
|
||||
int num_samples, vol_fadeout;
|
||||
char name[ 32 ], key_to_sample[ 97 ];
|
||||
char vib_type, vib_sweep, vib_depth, vib_rate;
|
||||
struct envelope vol_env, pan_env;
|
||||
struct sample *samples;
|
||||
};
|
||||
|
||||
struct pattern {
|
||||
int num_channels, num_rows;
|
||||
char *data;
|
||||
};
|
||||
|
||||
struct module {
|
||||
char name[ 32 ];
|
||||
int num_channels, num_instruments;
|
||||
int num_patterns, sequence_len, restart_pos;
|
||||
int default_gvol, default_speed, default_tempo, c2_rate, gain;
|
||||
int linear_periods, fast_vol_slides;
|
||||
unsigned char *default_panning, *sequence;
|
||||
struct pattern *patterns;
|
||||
struct instrument *instruments;
|
||||
};
|
||||
|
||||
/* 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. */
|
||||
struct module* module_load( struct data *data, char *message );
|
||||
/* Deallocate the specified module. */
|
||||
void dispose_module( struct module *module );
|
||||
/* Allocate and initialize a replay with the specified module and sampling rate. */
|
||||
struct replay* new_replay( struct module *module, int sample_rate, int interpolation );
|
||||
/* Deallocate the specified replay. */
|
||||
void dispose_replay( struct replay *replay );
|
||||
/* Returns the song duration in samples at the current sampling rate. */
|
||||
int replay_calculate_duration( struct replay *replay );
|
||||
/* Seek to approximately the specified sample position.
|
||||
The actual sample position reached is returned. */
|
||||
int replay_seek( struct replay *replay, int sample_pos );
|
||||
/* 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 );
|
||||
/* Generates audio and returns the number of stereo samples written into mix_buf. */
|
||||
int replay_get_audio( struct replay *replay, int *mix_buf );
|
||||
/* Returns the length of the output buffer required by replay_get_audio(). */
|
||||
int calculate_mix_buf_len( int sample_rate );
|
||||
|
||||
#endif
|
37
deps/ibxm/licence.txt
vendored
Normal file
37
deps/ibxm/licence.txt
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
Copyright (c) 2015, Martin Cameron
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the
|
||||
above copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization nor the names of
|
||||
its contributors may be used to endorse or promote
|
||||
products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---
|
@ -82,6 +82,9 @@ enum file_path_enum
|
||||
FILE_PATH_7Z_EXTENSION,
|
||||
FILE_PATH_OGG_EXTENSION,
|
||||
FILE_PATH_WAV_EXTENSION,
|
||||
FILE_PATH_MOD_EXTENSION,
|
||||
FILE_PATH_S3M_EXTENSION,
|
||||
FILE_PATH_XM_EXTENSION,
|
||||
FILE_PATH_CONFIG_EXTENSION,
|
||||
FILE_PATH_CORE_INFO_EXTENSION
|
||||
};
|
||||
|
@ -107,6 +107,15 @@ const char *file_path_str(enum file_path_enum enum_idx)
|
||||
case FILE_PATH_WAV_EXTENSION:
|
||||
str = ".wav";
|
||||
break;
|
||||
case FILE_PATH_MOD_EXTENSION:
|
||||
str = ".mod";
|
||||
break;
|
||||
case FILE_PATH_S3M_EXTENSION:
|
||||
str = ".s3m";
|
||||
break;
|
||||
case FILE_PATH_XM_EXTENSION:
|
||||
str = ".xm";
|
||||
break;
|
||||
case FILE_PATH_JPEG_EXTENSION:
|
||||
str = ".jpeg";
|
||||
break;
|
||||
|
@ -14,6 +14,8 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define HAVE_IBXM 1
|
||||
|
||||
#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL)
|
||||
#define HAVE_SHADERS
|
||||
#endif
|
||||
@ -350,6 +352,8 @@ VIDEO DRIVER
|
||||
#include "../gfx/drivers/gdi_gfx.c"
|
||||
#endif
|
||||
|
||||
#include "../deps/ibxm/ibxm.c"
|
||||
|
||||
/*============================================================
|
||||
FONTS
|
||||
============================================================ */
|
||||
|
@ -46,6 +46,10 @@
|
||||
#include "../../deps/stb/stb_vorbis.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IBXM
|
||||
#include "../../deps/ibxm/ibxm.h"
|
||||
#endif
|
||||
|
||||
#define AUDIO_MIXER_MAX_VOICES 8
|
||||
#define AUDIO_MIXER_TEMP_OGG_BUFFER 8192
|
||||
|
||||
@ -70,6 +74,15 @@ struct audio_mixer_sound
|
||||
const void* data;
|
||||
} ogg;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IBXM
|
||||
struct
|
||||
{
|
||||
/* mod/s3m/xm */
|
||||
unsigned size;
|
||||
const void* data;
|
||||
} mod;
|
||||
#endif
|
||||
} types;
|
||||
};
|
||||
|
||||
@ -103,6 +116,18 @@ struct audio_mixer_voice
|
||||
const retro_resampler_t *resampler;
|
||||
} ogg;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IBXM
|
||||
struct
|
||||
{
|
||||
/* mod/s3m/xm */
|
||||
unsigned position;
|
||||
unsigned samples;
|
||||
unsigned buf_samples;
|
||||
int* buffer;
|
||||
struct replay* stream;
|
||||
} mod;
|
||||
#endif
|
||||
} types;
|
||||
};
|
||||
|
||||
@ -319,6 +344,24 @@ audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size)
|
||||
#endif
|
||||
}
|
||||
|
||||
audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size)
|
||||
{
|
||||
#ifdef HAVE_IBXM
|
||||
audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
|
||||
|
||||
if (!sound)
|
||||
return NULL;
|
||||
|
||||
sound->type = AUDIO_MIXER_TYPE_MOD;
|
||||
sound->types.mod.size = size;
|
||||
sound->types.mod.data = buffer;
|
||||
|
||||
return sound;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void audio_mixer_destroy(audio_mixer_sound_t* sound)
|
||||
{
|
||||
void *handle = NULL;
|
||||
@ -337,6 +380,13 @@ void audio_mixer_destroy(audio_mixer_sound_t* sound)
|
||||
handle = (void*)sound->types.ogg.data;
|
||||
if (handle)
|
||||
free(handle);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_MOD:
|
||||
#ifdef HAVE_IBXM
|
||||
handle = (void*)sound->types.mod.data;
|
||||
if (handle)
|
||||
free(handle);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_NONE:
|
||||
@ -413,6 +463,65 @@ error:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IBXM
|
||||
static bool audio_mixer_play_mod(
|
||||
audio_mixer_sound_t* sound,
|
||||
audio_mixer_voice_t* voice,
|
||||
bool repeat, float volume,
|
||||
audio_mixer_stop_cb_t stop_cb)
|
||||
{
|
||||
int buf_samples = 0;
|
||||
int samples = 0;
|
||||
void *mod_buffer = NULL;
|
||||
struct module* module = NULL;
|
||||
struct replay* replay = NULL;
|
||||
struct data data;
|
||||
char message[64];
|
||||
|
||||
data.buffer = (char*)sound->types.ogg.data;
|
||||
data.length = sound->types.ogg.size;
|
||||
module = module_load(&data, message);
|
||||
if (module==NULL) {
|
||||
printf("audio_mixer_play_mod module_load() failed with error: %s\n", message);
|
||||
goto error;
|
||||
}
|
||||
|
||||
replay = new_replay( module, s_rate, 1);
|
||||
if (replay==NULL) {
|
||||
printf("audio_mixer_play_mod new_replay() failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf_samples = calculate_mix_buf_len(s_rate);
|
||||
mod_buffer = memalign_alloc(16, ((buf_samples + 15) & ~15) * sizeof(int));
|
||||
if (!mod_buffer) {
|
||||
printf("audio_mixer_play_mod cannot allocate mod_buffer !\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
samples = replay_calculate_duration(replay);
|
||||
if (!samples) {
|
||||
printf("audio_mixer_play_mod cannot retrieve duration !\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
voice->types.mod.buffer = mod_buffer;
|
||||
voice->types.mod.buf_samples = buf_samples;
|
||||
voice->types.mod.stream = replay;
|
||||
voice->types.mod.position = 0;
|
||||
voice->types.mod.samples = 0;//samples;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (mod_buffer)
|
||||
memalign_free(mod_buffer);
|
||||
dispose_module(module);
|
||||
return false;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
||||
float volume, audio_mixer_stop_cb_t stop_cb)
|
||||
{
|
||||
@ -440,6 +549,11 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
||||
case AUDIO_MIXER_TYPE_OGG:
|
||||
#ifdef HAVE_STB_VORBIS
|
||||
res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_MOD:
|
||||
#ifdef HAVE_IBXM
|
||||
res = audio_mixer_play_mod(sound, voice, repeat, volume, stop_cb);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_NONE:
|
||||
@ -608,6 +722,79 @@ again:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IBXM
|
||||
static void audio_mixer_mix_mod(float* buffer, size_t num_frames,
|
||||
audio_mixer_voice_t* voice,
|
||||
float volume)
|
||||
{
|
||||
int i;
|
||||
unsigned temp_samples = 0;
|
||||
unsigned buf_free = num_frames * 2;
|
||||
int* pcm = NULL;
|
||||
|
||||
if (voice->types.mod.position == voice->types.mod.samples)
|
||||
{
|
||||
again:
|
||||
temp_samples = replay_get_audio( voice->types.mod.stream, voice->types.mod.buffer );
|
||||
temp_samples *= 2; // stereo
|
||||
|
||||
if (temp_samples == 0)
|
||||
{
|
||||
if (voice->repeat)
|
||||
{
|
||||
if (voice->stop_cb)
|
||||
voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
|
||||
|
||||
replay_seek( voice->types.mod.stream, 0);
|
||||
goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (voice->stop_cb)
|
||||
voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
|
||||
|
||||
voice->type = AUDIO_MIXER_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
voice->types.mod.position = 0;
|
||||
voice->types.mod.samples = temp_samples;
|
||||
}
|
||||
pcm = voice->types.mod.buffer + voice->types.mod.position;
|
||||
|
||||
float samplef = 0.0f;
|
||||
int samplei = 0;
|
||||
if (voice->types.mod.samples < buf_free)
|
||||
{
|
||||
for (i = voice->types.mod.samples; i != 0; i--)
|
||||
{
|
||||
samplei = *pcm++ * volume;
|
||||
samplef = (float)((int)samplei + 32768) / 65535.0f;
|
||||
samplef = samplef * 2.0f - 1.0f;
|
||||
*buffer++ = samplef;
|
||||
}
|
||||
|
||||
buf_free -= voice->types.mod.samples;
|
||||
goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = buf_free; i != 0; --i )
|
||||
{
|
||||
samplei = *pcm++ * volume;
|
||||
samplef = (float)((int)samplei + 32768) / 65535.0f;
|
||||
samplef = samplef * 2.0f - 1.0f;
|
||||
*buffer++ = samplef;
|
||||
}
|
||||
|
||||
voice->types.mod.position += buf_free;
|
||||
voice->types.mod.samples -= buf_free;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bool override)
|
||||
{
|
||||
unsigned i;
|
||||
@ -631,6 +818,10 @@ void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bo
|
||||
case AUDIO_MIXER_TYPE_OGG:
|
||||
#ifdef HAVE_STB_VORBIS
|
||||
audio_mixer_mix_ogg(buffer, num_frames, voice, volume);
|
||||
#endif
|
||||
case AUDIO_MIXER_TYPE_MOD:
|
||||
#ifdef HAVE_IBXM
|
||||
audio_mixer_mix_mod(buffer, num_frames, voice, volume);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_NONE:
|
||||
|
@ -40,7 +40,8 @@ enum audio_mixer_type
|
||||
{
|
||||
AUDIO_MIXER_TYPE_NONE = 0,
|
||||
AUDIO_MIXER_TYPE_WAV,
|
||||
AUDIO_MIXER_TYPE_OGG
|
||||
AUDIO_MIXER_TYPE_OGG,
|
||||
AUDIO_MIXER_TYPE_MOD
|
||||
};
|
||||
|
||||
typedef struct audio_mixer_sound audio_mixer_sound_t;
|
||||
@ -59,6 +60,7 @@ void audio_mixer_done(void);
|
||||
|
||||
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size);
|
||||
audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size);
|
||||
audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size);
|
||||
|
||||
void audio_mixer_destroy(audio_mixer_sound_t* sound);
|
||||
|
||||
|
@ -6436,6 +6436,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
|
||||
#endif
|
||||
#ifdef HAVE_RTGA
|
||||
string_list_append(str_list, "tga", attr);
|
||||
#endif
|
||||
#ifdef HAVE_IBXM
|
||||
string_list_append(str_list, "mod", attr);
|
||||
string_list_append(str_list, "s3m", attr);
|
||||
string_list_append(str_list, "xm", attr);
|
||||
#endif
|
||||
string_list_join_concat(info->exts, sizeof(info->exts), str_list, "|");
|
||||
string_list_free(str_list);
|
||||
|
11
msg_hash.c
11
msg_hash.c
@ -169,6 +169,9 @@ uint32_t msg_hash_calculate(const char *s)
|
||||
#define MENU_VALUE_FILE_MP3 0x0b889135U
|
||||
#define MENU_VALUE_FILE_FLAC 0x7c96d67bU
|
||||
#define MENU_VALUE_FILE_OGG 0x0b8898c2U
|
||||
#define MENU_VALUE_FILE_MOD 0x0b889145U
|
||||
#define MENU_VALUE_FILE_S3M 0x0b88a318U
|
||||
#define MENU_VALUE_FILE_XM 0x00597a2aU
|
||||
#define MENU_VALUE_FILE_FLV 0x0b88732dU
|
||||
#define MENU_VALUE_FILE_WAV 0x0b88ba13U
|
||||
#define MENU_VALUE_FILE_MOV 0x0b889157U
|
||||
@ -347,6 +350,14 @@ enum msg_file_type msg_hash_to_file_type(uint32_t hash)
|
||||
case MENU_VALUE_FILE_WMA:
|
||||
return FILE_TYPE_WMA;
|
||||
#endif
|
||||
#ifdef HAVE_IBXM
|
||||
case MENU_VALUE_FILE_MOD:
|
||||
return FILE_TYPE_MOD;
|
||||
case MENU_VALUE_FILE_S3M:
|
||||
return FILE_TYPE_S3M;
|
||||
case MENU_VALUE_FILE_XM:
|
||||
return FILE_TYPE_XM;
|
||||
#endif
|
||||
#ifdef HAVE_IMAGEVIEWER
|
||||
case MENU_VALUE_FILE_JPG:
|
||||
case MENU_VALUE_FILE_JPG_CAPS:
|
||||
|
@ -127,6 +127,10 @@ enum msg_file_type
|
||||
FILE_TYPE_TGA,
|
||||
FILE_TYPE_BMP,
|
||||
|
||||
FILE_TYPE_MOD,
|
||||
FILE_TYPE_S3M,
|
||||
FILE_TYPE_XM,
|
||||
|
||||
FILE_TYPE_CUE,
|
||||
FILE_TYPE_ISO,
|
||||
FILE_TYPE_LUTRO,
|
||||
|
7
paths.c
7
paths.c
@ -744,6 +744,13 @@ enum rarch_content_type path_is_media_type(const char *path)
|
||||
case FILE_TYPE_BMP:
|
||||
return RARCH_CONTENT_IMAGE;
|
||||
#endif
|
||||
#ifdef HAVE_IBXM
|
||||
case FILE_TYPE_MOD:
|
||||
case FILE_TYPE_S3M:
|
||||
case FILE_TYPE_XM:
|
||||
return RARCH_CONTENT_MUSIC;
|
||||
#endif
|
||||
|
||||
case FILE_TYPE_NONE:
|
||||
default:
|
||||
break;
|
||||
|
@ -71,6 +71,7 @@ HAVE_FREETYPE=auto # FreeType support
|
||||
HAVE_STB_FONT=yes # stb_truetype font support
|
||||
HAVE_STB_IMAGE=yes # stb image loading support
|
||||
HAVE_STB_VORBIS=yes # stb vorbis support
|
||||
HAVE_IBXM=yes # IBXM support
|
||||
HAVE_XVIDEO=auto # XVideo support
|
||||
HAVE_PYTHON=no # Python 3 support for shaders
|
||||
C89_PYTHON=no
|
||||
|
@ -99,6 +99,28 @@ static void task_audio_mixer_handle_upload_ogg(void *task_data,
|
||||
free(user_data);
|
||||
}
|
||||
|
||||
static void task_audio_mixer_handle_upload_mod(void *task_data,
|
||||
void *user_data, const char *err)
|
||||
{
|
||||
audio_mixer_stream_params_t params;
|
||||
nbio_buf_t *img = (nbio_buf_t*)task_data;
|
||||
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
params.volume = 1.0f;
|
||||
params.type = AUDIO_MIXER_TYPE_MOD;
|
||||
params.state = AUDIO_STREAM_STATE_PLAYING;
|
||||
params.buf = img->buf;
|
||||
params.bufsize = img->bufsize;
|
||||
params.cb = NULL;
|
||||
|
||||
audio_driver_mixer_add_stream(¶ms);
|
||||
|
||||
free(img);
|
||||
free(user_data);
|
||||
}
|
||||
|
||||
static void task_audio_mixer_handle_upload_wav(void *task_data,
|
||||
void *user_data, const char *err)
|
||||
{
|
||||
@ -191,6 +213,14 @@ bool task_push_audio_mixer_load(const char *fullpath, retro_task_callback_t cb,
|
||||
nbio->type = NBIO_TYPE_OGG;
|
||||
t->callback = task_audio_mixer_handle_upload_ogg;
|
||||
}
|
||||
else if ( strstr(fullpath, file_path_str(FILE_PATH_MOD_EXTENSION)) ||
|
||||
strstr(fullpath, file_path_str(FILE_PATH_S3M_EXTENSION)) ||
|
||||
strstr(fullpath, file_path_str(FILE_PATH_XM_EXTENSION)))
|
||||
{
|
||||
image->type = AUDIO_MIXER_TYPE_MOD;
|
||||
nbio->type = NBIO_TYPE_MOD;
|
||||
t->callback = task_audio_mixer_handle_upload_mod;
|
||||
}
|
||||
|
||||
nbio->data = (struct audio_mixer_handle*)image;
|
||||
nbio->is_finished = false;
|
||||
|
@ -104,6 +104,7 @@ void task_file_load_handler(retro_task_t *task)
|
||||
task_set_finished(task, true);
|
||||
break;
|
||||
case NBIO_TYPE_OGG:
|
||||
case NBIO_TYPE_MOD:
|
||||
case NBIO_TYPE_WAV:
|
||||
if (!task_audio_mixer_load_handler(task))
|
||||
task_set_finished(task, true);
|
||||
|
@ -74,6 +74,7 @@ enum nbio_type
|
||||
NBIO_TYPE_TGA,
|
||||
NBIO_TYPE_BMP,
|
||||
NBIO_TYPE_OGG,
|
||||
NBIO_TYPE_MOD,
|
||||
NBIO_TYPE_WAV
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user