diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp')
-rw-r--r-- | Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp b/Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp new file mode 100644 index 00000000..646b3807 --- /dev/null +++ b/Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp @@ -0,0 +1,139 @@ +#include "api__in_mod.h" +#include <libopenmpt/libopenmpt.h> +#include "../nsutil/pcm.h" + +static const size_t kModBufferSize = 512; +static const unsigned int kModSampleRate = 44100; // TODO(benski) configurable! + +openmpt_module *OpenMod(const wchar_t *filename); + +class PlayParams +{ +public: + PlayParams(); + ~PlayParams(); + openmpt_module *mod; + float *buffer; + int bps; + int channels; + int sample_rate; + bool use_float; + size_t (*openmpt_read)(openmpt_module * mod, int32_t samplerate, size_t count, float *interleaved_stereo); +}; + +PlayParams::PlayParams() +{ + mod = 0; + buffer = 0; +} + +PlayParams::~PlayParams() +{ + openmpt_module_destroy(mod); + free(buffer); + +} + +static PlayParams *ExtendedOpen(const wchar_t *fn, int *size, int *bps, int *nch, int *srate, bool use_float) +{ + float *float_buffer = 0; + size_t (*openmpt_read)(openmpt_module * mod, int32_t samplerate, size_t count, float *interleaved_stereo)=openmpt_module_read_interleaved_float_stereo; + + openmpt_module *mod = OpenMod(fn); + if (!mod) { + return 0; + } + + int requested_channels = *nch; + int requested_bits = *bps; + int requested_srate = *srate; + + if (!requested_channels) { + requested_channels=2; + } + + if (!requested_bits) { + if (use_float) { + requested_bits=32; + } else { + requested_bits=16; + } + } + + if (!requested_srate) { + requested_srate = kModSampleRate; + } + + if (requested_channels == 1) { + openmpt_read = openmpt_module_read_float_mono; + } else if (requested_channels < 4) { + requested_channels = 2; + openmpt_read = openmpt_module_read_interleaved_float_stereo; + } else if (requested_channels) { + requested_channels = 4; + openmpt_read = openmpt_module_read_interleaved_float_quad; + } + + if (!use_float) { + float_buffer = (float *)malloc(sizeof(float) * kModBufferSize * requested_channels); + if (!float_buffer) { + openmpt_module_destroy(mod); + return 0; + } + } + + PlayParams *play_params = new PlayParams; + if (!play_params) { + openmpt_module_destroy(mod); + free(float_buffer); + return 0; + } + + play_params->mod = mod; + play_params->buffer = float_buffer; + play_params->bps = requested_bits; + play_params->channels = requested_channels; + play_params->use_float = use_float; + play_params->openmpt_read = openmpt_read; + play_params->sample_rate = requested_srate; + + *nch = requested_channels; + *srate = requested_srate; + *bps = requested_bits; + + *size = (int)(openmpt_module_get_duration_seconds(mod) * (double)requested_bits * (double)requested_srate * (double)requested_channels / 8.0); + + return play_params; +} +extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW_float(const wchar_t *fn, int *size, int *bps, int *nch, int *srate) +{ + return (intptr_t)ExtendedOpen(fn, size, bps, nch, srate, true); +} + +extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW(const wchar_t *fn, int *size, int *bps, int *nch, int *srate) +{ + return (intptr_t)ExtendedOpen(fn, size, bps, nch, srate, false); +} + +extern "C" __declspec(dllexport) size_t winampGetExtendedRead_getData(intptr_t handle, char *dest, size_t len, int *killswitch) +{ + PlayParams *play_params = (PlayParams *)handle; + size_t requested_samples = len / (play_params->channels * play_params->bps/8); + + if (play_params->use_float) { + return play_params->openmpt_read(play_params->mod, play_params->sample_rate, requested_samples, (float *)dest) * sizeof(float) * play_params->channels; + } else { + if (requested_samples > kModBufferSize) { + requested_samples = kModBufferSize; + } + size_t count = play_params->openmpt_read(play_params->mod, play_params->sample_rate, requested_samples, play_params->buffer); + nsutil_pcm_FloatToInt_Interleaved(dest, play_params->buffer, play_params->bps, play_params->channels*count); + return count * play_params->bps * play_params->channels / 8; + } +} + +extern "C" __declspec(dllexport) void winampGetExtendedRead_close(intptr_t handle) +{ + PlayParams *play_params = (PlayParams *)handle; + delete play_params; +}
\ No newline at end of file |