1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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;
}
|