miniaudio 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/miniaudio/convert_functions.h +118 -0
- data/ext/miniaudio/rb-miniaudio.c +5 -237
- data/ext/miniaudio/read_functions.h +241 -0
- data/lib/miniaudio.rb +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 306f78eb852bb174b8633fc9ad08aa6326781cd093dbd73273d08c443abc6dc7
|
4
|
+
data.tar.gz: cc91095d14079ae4a07ab781aadc9b3d1ba1a56fef79d6a9004dc30b9287ce77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10af5458bab8aaafe256dacbf00d7c1c91933c6d05592e721a81307562e9f888b44e619edd53f83f8cbe66b91866628a14a937a95ca4447ad84cf4037f71085a
|
7
|
+
data.tar.gz: c44b2f23f95db3c3d9d7e1014b7cbb1d82d4a8d6c376f470aeedefd776a39587cf706cd1c1337df4d7d1b4e518d01dab18cfef812761f9bc462c26abdde288a2
|
@@ -0,0 +1,118 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
|
5
|
+
#define MINIAUDIO_IMPLEMENTATION
|
6
|
+
#include "miniaudio/miniaudio.h"
|
7
|
+
|
8
|
+
static const char* MA_SAMPLE_FORMAT_U8 = "u8";
|
9
|
+
static const char* MA_SAMPLE_FORMAT_S16 = "s16";
|
10
|
+
static const char* MA_SAMPLE_FORMAT_S24 = "s24";
|
11
|
+
static const char* MA_SAMPLE_FORMAT_S32 = "s32";
|
12
|
+
static const char* MA_SAMPLE_FORMAT_F32 = "f32";
|
13
|
+
|
14
|
+
#define CHECK_CHANNELS_NUM(rb, c, err) \
|
15
|
+
int c = NUM2INT(rb); \
|
16
|
+
if (c < MA_MIN_CHANNELS || c > MA_MAX_CHANNELS) { \
|
17
|
+
rb_raise(rb_eArgError, err, MA_MIN_CHANNELS, MA_MAX_CHANNELS); \
|
18
|
+
}
|
19
|
+
|
20
|
+
#define CHECK_SAMPLE_RATE(rb, c, err) \
|
21
|
+
int c = NUM2INT(rb); \
|
22
|
+
if (c < MA_MIN_SAMPLE_RATE || c > MA_MAX_SAMPLE_RATE) { \
|
23
|
+
rb_raise(rb_eArgError, err, MA_MIN_SAMPLE_RATE, MA_MAX_SAMPLE_RATE);\
|
24
|
+
}
|
25
|
+
|
26
|
+
#define CHECK_SAMPLE_FORMAT(rb, c, err) \
|
27
|
+
ma_format c = ma_format_unknown; \
|
28
|
+
if (ID2SYM(rb_intern(MA_SAMPLE_FORMAT_U8)) == rb) { \
|
29
|
+
c = ma_format_u8; \
|
30
|
+
} else if (ID2SYM(rb_intern(MA_SAMPLE_FORMAT_S16)) == rb) { \
|
31
|
+
c = ma_format_s16; \
|
32
|
+
} else if (ID2SYM(rb_intern(MA_SAMPLE_FORMAT_S24)) == rb) { \
|
33
|
+
c = ma_format_s24; \
|
34
|
+
} else if (ID2SYM(rb_intern(MA_SAMPLE_FORMAT_S32)) == rb) { \
|
35
|
+
c = ma_format_s32; \
|
36
|
+
} else if (ID2SYM(rb_intern(MA_SAMPLE_FORMAT_F32)) == rb) { \
|
37
|
+
c = ma_format_f32; \
|
38
|
+
} else { \
|
39
|
+
rb_raise(rb_eArgError, "Unknown %s sample format: %+"PRIsVALUE". Allowed: :u8, :s16, :s24, :s32, :f32", err, rb); \
|
40
|
+
}
|
41
|
+
|
42
|
+
static int sample_width(ma_format ma_fmt) {
|
43
|
+
switch (ma_fmt) {
|
44
|
+
case ma_format_u8:
|
45
|
+
return 1;
|
46
|
+
case ma_format_s16:
|
47
|
+
return 2;
|
48
|
+
case ma_format_s24:
|
49
|
+
return 3;
|
50
|
+
case ma_format_s32:
|
51
|
+
case ma_format_f32:
|
52
|
+
return 4;
|
53
|
+
default:
|
54
|
+
return 0;
|
55
|
+
}
|
56
|
+
return 0;
|
57
|
+
}
|
58
|
+
|
59
|
+
static VALUE rb_ma_convert_frames(
|
60
|
+
VALUE mod, VALUE rb_source,
|
61
|
+
VALUE rb_source_format, VALUE rb_source_channels, VALUE rb_source_sample_rate,
|
62
|
+
VALUE rb_dst_format, VALUE rb_dst_channels, VALUE rb_dst_sample_rate) {
|
63
|
+
|
64
|
+
CHECK_CHANNELS_NUM(
|
65
|
+
rb_source_channels, source_channels,
|
66
|
+
"Source channel count must be in %d..%d range"
|
67
|
+
)
|
68
|
+
|
69
|
+
CHECK_CHANNELS_NUM(
|
70
|
+
rb_dst_channels, dst_channels,
|
71
|
+
"Target channel count must be in %d..%d range"
|
72
|
+
)
|
73
|
+
|
74
|
+
CHECK_SAMPLE_RATE(
|
75
|
+
rb_source_sample_rate, source_sample_rate,
|
76
|
+
"Source sample rate must be in %d..%d range"
|
77
|
+
)
|
78
|
+
|
79
|
+
CHECK_SAMPLE_RATE(
|
80
|
+
rb_dst_sample_rate, dst_sample_rate,
|
81
|
+
"Target sample rate must be in %d..%d range"
|
82
|
+
)
|
83
|
+
|
84
|
+
CHECK_SAMPLE_FORMAT(rb_source_format, source_format, "source")
|
85
|
+
CHECK_SAMPLE_FORMAT(rb_dst_format, dst_format, "target")
|
86
|
+
|
87
|
+
int source_sample_width = sample_width(source_format);
|
88
|
+
int num_frames = RSTRING_LEN(rb_source) / source_sample_width / source_channels;
|
89
|
+
int dst_sample_width = sample_width(dst_format);
|
90
|
+
int num_out_frames = ma_calculate_frame_count_after_resampling(dst_sample_rate, source_sample_rate, num_frames);
|
91
|
+
|
92
|
+
int mem_len = num_out_frames * dst_sample_width * dst_channels;
|
93
|
+
void *converted = malloc(mem_len);
|
94
|
+
|
95
|
+
ma_uint64 res = ma_convert_frames(
|
96
|
+
converted, num_out_frames,
|
97
|
+
dst_format, dst_channels, dst_sample_rate,
|
98
|
+
StringValuePtr(rb_source), num_frames,
|
99
|
+
source_format, source_channels, source_sample_rate
|
100
|
+
);
|
101
|
+
|
102
|
+
if (res == 0) {
|
103
|
+
free(converted);
|
104
|
+
return Qnil;
|
105
|
+
}
|
106
|
+
|
107
|
+
int bytes_used = num_frames * source_sample_width * source_channels;
|
108
|
+
VALUE output = rb_str_new(converted, mem_len);
|
109
|
+
free(converted);
|
110
|
+
VALUE ret = rb_ary_new();
|
111
|
+
rb_ary_push(ret, output);
|
112
|
+
rb_ary_push(ret, INT2NUM(bytes_used));
|
113
|
+
return ret;
|
114
|
+
}
|
115
|
+
|
116
|
+
void define_convert_functions_under(VALUE mod) {
|
117
|
+
rb_define_module_function(mod, "convert_frames", &rb_ma_convert_frames, 7);
|
118
|
+
}
|
@@ -1,242 +1,10 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
|
3
|
-
#
|
4
|
-
#include "
|
5
|
-
|
6
|
-
#define MINIAUDIO_IMPLEMENTATION
|
7
|
-
#include "miniaudio/miniaudio.h"
|
8
|
-
|
9
|
-
// The stb_vorbis implementation must come after the implementation of miniaudio.
|
10
|
-
#undef STB_VORBIS_HEADER_ONLY
|
11
|
-
#include "miniaudio/extras/stb_vorbis.c"
|
12
|
-
|
13
|
-
#define OPEN_FILE(FORMAT, FRAME_TYPE, CODE) \
|
14
|
-
static VALUE rb_dr ## FORMAT ## _open_file_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE filename) { \
|
15
|
-
if (TYPE(filename) != T_STRING) { \
|
16
|
-
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Filename must be a string"); \
|
17
|
-
} \
|
18
|
-
\
|
19
|
-
unsigned int num_channels; \
|
20
|
-
unsigned int sample_rate; \
|
21
|
-
dr ## FORMAT ## _uint64 total_frames; \
|
22
|
-
\
|
23
|
-
FRAME_TYPE * frames = dr ## FORMAT ## _open_file_and_read_pcm_frames_ ## CODE (\
|
24
|
-
StringValuePtr(filename),\
|
25
|
-
&num_channels,\
|
26
|
-
&sample_rate,\
|
27
|
-
&total_frames,\
|
28
|
-
NULL\
|
29
|
-
);\
|
30
|
-
\
|
31
|
-
if (frames == NULL) {\
|
32
|
-
return Qnil;\
|
33
|
-
}\
|
34
|
-
\
|
35
|
-
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*total_frames);\
|
36
|
-
dr ## FORMAT ## _free(frames, NULL);\
|
37
|
-
VALUE ret = rb_ary_new();\
|
38
|
-
rb_ary_push(ret, ret_str);\
|
39
|
-
rb_ary_push(ret, INT2NUM(sample_rate));\
|
40
|
-
rb_ary_push(ret, INT2NUM(num_channels));\
|
41
|
-
rb_ary_push(ret, INT2NUM(total_frames));\
|
42
|
-
return ret;\
|
43
|
-
}
|
44
|
-
|
45
|
-
#define OPEN_MP3_FILE(FRAME_TYPE, CODE) \
|
46
|
-
static VALUE rb_drmp3_open_file_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE filename) { \
|
47
|
-
if (TYPE(filename) != T_STRING) { \
|
48
|
-
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Filename must be a string"); \
|
49
|
-
} \
|
50
|
-
\
|
51
|
-
drmp3_uint64 total_frames; \
|
52
|
-
\
|
53
|
-
drmp3_config config;\
|
54
|
-
FRAME_TYPE * frames = drmp3_open_file_and_read_pcm_frames_ ## CODE (\
|
55
|
-
StringValueCStr(filename),\
|
56
|
-
&config,\
|
57
|
-
&total_frames,\
|
58
|
-
NULL\
|
59
|
-
);\
|
60
|
-
\
|
61
|
-
if (frames == NULL) {\
|
62
|
-
return Qnil;\
|
63
|
-
}\
|
64
|
-
\
|
65
|
-
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*total_frames*config.channels);\
|
66
|
-
drmp3_free(frames, NULL);\
|
67
|
-
VALUE ary = rb_ary_new_from_args(4, ret_str, INT2NUM(config.sampleRate), INT2NUM(config.channels), INT2NUM(total_frames));\
|
68
|
-
return ary;\
|
69
|
-
}
|
70
|
-
|
71
|
-
#define OPEN_MEMORY(FORMAT, FRAME_TYPE, CODE) \
|
72
|
-
static VALUE rb_dr ## FORMAT ## _open_memory_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE str) { \
|
73
|
-
if (TYPE(str) != T_STRING) { \
|
74
|
-
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Memory storage must be a string"); \
|
75
|
-
} \
|
76
|
-
\
|
77
|
-
unsigned int num_channels; \
|
78
|
-
unsigned int sample_rate; \
|
79
|
-
dr ## FORMAT ## _uint64 total_frames; \
|
80
|
-
\
|
81
|
-
FRAME_TYPE * frames = dr ## FORMAT ## _open_memory_and_read_pcm_frames_ ## CODE (\
|
82
|
-
StringValuePtr(str),\
|
83
|
-
RSTRING_LEN(str),\
|
84
|
-
&num_channels,\
|
85
|
-
&sample_rate,\
|
86
|
-
&total_frames,\
|
87
|
-
NULL\
|
88
|
-
);\
|
89
|
-
\
|
90
|
-
if (frames == NULL) {\
|
91
|
-
return Qnil;\
|
92
|
-
}\
|
93
|
-
\
|
94
|
-
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*total_frames);\
|
95
|
-
dr ## FORMAT ## _free(frames, NULL);\
|
96
|
-
VALUE ret = rb_ary_new();\
|
97
|
-
rb_ary_push(ret, ret_str);\
|
98
|
-
rb_ary_push(ret, INT2NUM(sample_rate));\
|
99
|
-
rb_ary_push(ret, INT2NUM(num_channels));\
|
100
|
-
rb_ary_push(ret, INT2NUM(total_frames));\
|
101
|
-
return ret;\
|
102
|
-
}
|
103
|
-
|
104
|
-
#define OPEN_MP3_MEMORY(FRAME_TYPE, CODE) \
|
105
|
-
static VALUE rb_drmp3_open_memory_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE str) { \
|
106
|
-
if (TYPE(str) != T_STRING) { \
|
107
|
-
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Memory must be a string"); \
|
108
|
-
} \
|
109
|
-
\
|
110
|
-
drmp3_uint64 total_frames; \
|
111
|
-
\
|
112
|
-
drmp3_config config;\
|
113
|
-
FRAME_TYPE * frames = drmp3_open_memory_and_read_pcm_frames_ ## CODE (\
|
114
|
-
StringValuePtr(str),\
|
115
|
-
RSTRING_LEN(str),\
|
116
|
-
&config,\
|
117
|
-
&total_frames,\
|
118
|
-
NULL\
|
119
|
-
);\
|
120
|
-
\
|
121
|
-
if (frames == NULL) {\
|
122
|
-
return Qnil;\
|
123
|
-
}\
|
124
|
-
\
|
125
|
-
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*total_frames);\
|
126
|
-
drmp3_free(frames, NULL);\
|
127
|
-
VALUE ret = rb_ary_new();\
|
128
|
-
rb_ary_push(ret, ret_str);\
|
129
|
-
rb_ary_push(ret, INT2NUM(config.sampleRate));\
|
130
|
-
rb_ary_push(ret, INT2NUM(config.channels));\
|
131
|
-
rb_ary_push(ret, INT2NUM(total_frames));\
|
132
|
-
return ret;\
|
133
|
-
}
|
134
|
-
|
135
|
-
static VALUE rb_stb_vorbis_decode_filename_s16 (VALUE mod, VALUE filename) {
|
136
|
-
if (TYPE(filename) != T_STRING) {
|
137
|
-
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Filename must be a string");
|
138
|
-
}
|
139
|
-
|
140
|
-
int num_channels;
|
141
|
-
int sample_rate;
|
142
|
-
int64_t total_frames;
|
143
|
-
|
144
|
-
int16_t *output;
|
145
|
-
|
146
|
-
total_frames = stb_vorbis_decode_filename (
|
147
|
-
StringValueCStr(filename),
|
148
|
-
&num_channels,
|
149
|
-
&sample_rate,
|
150
|
-
&output
|
151
|
-
);
|
152
|
-
|
153
|
-
if (total_frames < 0) {
|
154
|
-
return Qnil;
|
155
|
-
}
|
156
|
-
|
157
|
-
VALUE ret_str = rb_str_new((char*)output, sizeof(int16_t)*total_frames);
|
158
|
-
free(output);
|
159
|
-
VALUE ret = rb_ary_new();
|
160
|
-
rb_ary_push(ret, ret_str);
|
161
|
-
rb_ary_push(ret, INT2NUM(sample_rate));
|
162
|
-
rb_ary_push(ret, INT2NUM(num_channels));
|
163
|
-
rb_ary_push(ret, INT2NUM(total_frames));
|
164
|
-
return ret;
|
165
|
-
}
|
166
|
-
|
167
|
-
static VALUE rb_stb_vorbis_decode_memory_s16(VALUE mod, VALUE str) {
|
168
|
-
if (TYPE(str) != T_STRING) {
|
169
|
-
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Memory storage must be a string");
|
170
|
-
}
|
171
|
-
|
172
|
-
int num_channels;
|
173
|
-
int sample_rate;
|
174
|
-
int64_t total_frames;
|
175
|
-
|
176
|
-
int16_t *output;
|
177
|
-
|
178
|
-
total_frames = stb_vorbis_decode_memory(
|
179
|
-
(uint8*)StringValuePtr(str),
|
180
|
-
RSTRING_LEN(str),
|
181
|
-
&num_channels,
|
182
|
-
&sample_rate,
|
183
|
-
&output
|
184
|
-
);
|
185
|
-
|
186
|
-
if (total_frames < 0) {
|
187
|
-
return Qnil;
|
188
|
-
}
|
189
|
-
|
190
|
-
VALUE ret_str = rb_str_new((char*)output, sizeof(int16_t)*total_frames);
|
191
|
-
free(output);
|
192
|
-
VALUE ret = rb_ary_new();
|
193
|
-
rb_ary_push(ret, ret_str);
|
194
|
-
rb_ary_push(ret, INT2NUM(sample_rate));
|
195
|
-
rb_ary_push(ret, INT2NUM(num_channels));
|
196
|
-
rb_ary_push(ret, INT2NUM(total_frames));
|
197
|
-
return ret;
|
198
|
-
}
|
199
|
-
|
200
|
-
OPEN_FILE(wav, int16_t, s16)
|
201
|
-
OPEN_FILE(wav, int32_t, s32)
|
202
|
-
OPEN_FILE(wav, float, f32)
|
203
|
-
|
204
|
-
OPEN_MP3_FILE(int16_t, s16)
|
205
|
-
OPEN_MP3_FILE(float, f32)
|
206
|
-
|
207
|
-
OPEN_FILE(flac, int16_t, s16)
|
208
|
-
OPEN_FILE(flac, int32_t, s32)
|
209
|
-
OPEN_FILE(flac, float, f32)
|
210
|
-
|
211
|
-
OPEN_MEMORY(wav, int16_t, s16)
|
212
|
-
OPEN_MEMORY(wav, int32_t, s32)
|
213
|
-
OPEN_MEMORY(wav, float, f32)
|
214
|
-
|
215
|
-
OPEN_MP3_MEMORY(int16_t, s16)
|
216
|
-
OPEN_MP3_MEMORY(float, f32)
|
217
|
-
|
218
|
-
OPEN_MEMORY(flac, int16_t, s16)
|
219
|
-
OPEN_MEMORY(flac, int32_t, s32)
|
220
|
-
OPEN_MEMORY(flac, float, f32)
|
3
|
+
#include "read_functions.h"
|
4
|
+
#include "convert_functions.h"
|
221
5
|
|
222
6
|
void Init_miniaudio(void) {
|
223
|
-
VALUE
|
224
|
-
|
225
|
-
|
226
|
-
rb_define_module_function(mod, "wav_read_file_f32", &rb_drwav_open_file_and_read_pcm_frames_f32, 1);
|
227
|
-
rb_define_module_function(mod, "mp3_read_file_s16", rb_drmp3_open_file_and_read_pcm_frames_s16, 1);
|
228
|
-
rb_define_module_function(mod, "mp3_read_file_f32", rb_drmp3_open_file_and_read_pcm_frames_f32, 1);
|
229
|
-
rb_define_module_function(mod, "flac_read_file_s16", &rb_drflac_open_file_and_read_pcm_frames_s16, 1);
|
230
|
-
rb_define_module_function(mod, "flac_read_file_s32", &rb_drflac_open_file_and_read_pcm_frames_s32, 1);
|
231
|
-
rb_define_module_function(mod, "flac_read_file_f32", &rb_drflac_open_file_and_read_pcm_frames_f32, 1);
|
232
|
-
rb_define_module_function(mod, "vorbis_read_file_s16", &rb_stb_vorbis_decode_filename_s16, 1);
|
233
|
-
rb_define_module_function(mod, "wav_read_s16", &rb_drwav_open_memory_and_read_pcm_frames_s16, 1);
|
234
|
-
rb_define_module_function(mod, "wav_read_s32", &rb_drwav_open_memory_and_read_pcm_frames_s32, 1);
|
235
|
-
rb_define_module_function(mod, "wav_read_f32", &rb_drwav_open_memory_and_read_pcm_frames_f32, 1);
|
236
|
-
rb_define_module_function(mod, "mp3_read_s16", rb_drmp3_open_memory_and_read_pcm_frames_s16, 1);
|
237
|
-
rb_define_module_function(mod, "mp3_read_f32", rb_drmp3_open_memory_and_read_pcm_frames_f32, 1);
|
238
|
-
rb_define_module_function(mod, "flac_read_s16", &rb_drflac_open_memory_and_read_pcm_frames_s16, 1);
|
239
|
-
rb_define_module_function(mod, "flac_read_s32", &rb_drflac_open_memory_and_read_pcm_frames_s32, 1);
|
240
|
-
rb_define_module_function(mod, "flac_read_f32", &rb_drflac_open_memory_and_read_pcm_frames_f32, 1);
|
241
|
-
rb_define_module_function(mod, "vorbis_file_s16", &rb_stb_vorbis_decode_memory_s16, 1);
|
7
|
+
VALUE rb_cMod = rb_const_get(rb_cObject, rb_intern("Miniaudio"));
|
8
|
+
define_read_functions_under(rb_cMod);
|
9
|
+
define_convert_functions_under(rb_cMod);
|
242
10
|
}
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#define STB_VORBIS_HEADER_ONLY
|
4
|
+
#include "miniaudio/extras/stb_vorbis.c" // Enables Vorbis decoding.
|
5
|
+
|
6
|
+
#define MINIAUDIO_IMPLEMENTATION
|
7
|
+
#include "miniaudio/miniaudio.h"
|
8
|
+
|
9
|
+
// The stb_vorbis implementation must come after the implementation of miniaudio.
|
10
|
+
#undef STB_VORBIS_HEADER_ONLY
|
11
|
+
#include "miniaudio/extras/stb_vorbis.c"
|
12
|
+
|
13
|
+
#define OPEN_FILE(FORMAT, FRAME_TYPE, CODE) \
|
14
|
+
static VALUE rb_dr ## FORMAT ## _open_file_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE filename) { \
|
15
|
+
if (TYPE(filename) != T_STRING) { \
|
16
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Filename must be a string"); \
|
17
|
+
} \
|
18
|
+
\
|
19
|
+
unsigned int num_channels; \
|
20
|
+
unsigned int sample_rate; \
|
21
|
+
dr ## FORMAT ## _uint64 total_frames; \
|
22
|
+
\
|
23
|
+
FRAME_TYPE * frames = dr ## FORMAT ## _open_file_and_read_pcm_frames_ ## CODE (\
|
24
|
+
StringValuePtr(filename),\
|
25
|
+
&num_channels,\
|
26
|
+
&sample_rate,\
|
27
|
+
&total_frames,\
|
28
|
+
NULL\
|
29
|
+
);\
|
30
|
+
\
|
31
|
+
if (frames == NULL) {\
|
32
|
+
return Qnil;\
|
33
|
+
}\
|
34
|
+
\
|
35
|
+
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*num_channels*total_frames);\
|
36
|
+
dr ## FORMAT ## _free(frames, NULL);\
|
37
|
+
VALUE ret = rb_ary_new();\
|
38
|
+
rb_ary_push(ret, ret_str);\
|
39
|
+
rb_ary_push(ret, INT2NUM(sample_rate));\
|
40
|
+
rb_ary_push(ret, INT2NUM(num_channels));\
|
41
|
+
rb_ary_push(ret, INT2NUM(total_frames));\
|
42
|
+
return ret;\
|
43
|
+
}
|
44
|
+
|
45
|
+
#define OPEN_MP3_FILE(FRAME_TYPE, CODE) \
|
46
|
+
static VALUE rb_drmp3_open_file_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE filename) { \
|
47
|
+
if (TYPE(filename) != T_STRING) { \
|
48
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Filename must be a string"); \
|
49
|
+
} \
|
50
|
+
\
|
51
|
+
drmp3_uint64 total_frames; \
|
52
|
+
\
|
53
|
+
drmp3_config config;\
|
54
|
+
FRAME_TYPE * frames = drmp3_open_file_and_read_pcm_frames_ ## CODE (\
|
55
|
+
StringValueCStr(filename),\
|
56
|
+
&config,\
|
57
|
+
&total_frames,\
|
58
|
+
NULL\
|
59
|
+
);\
|
60
|
+
\
|
61
|
+
if (frames == NULL) {\
|
62
|
+
return Qnil;\
|
63
|
+
}\
|
64
|
+
\
|
65
|
+
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*total_frames*config.channels);\
|
66
|
+
drmp3_free(frames, NULL);\
|
67
|
+
VALUE ary = rb_ary_new_from_args(4, ret_str, INT2NUM(config.sampleRate), INT2NUM(config.channels), INT2NUM(total_frames));\
|
68
|
+
return ary;\
|
69
|
+
}
|
70
|
+
|
71
|
+
#define OPEN_MEMORY(FORMAT, FRAME_TYPE, CODE) \
|
72
|
+
static VALUE rb_dr ## FORMAT ## _open_memory_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE str) { \
|
73
|
+
if (TYPE(str) != T_STRING) { \
|
74
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Memory storage must be a string"); \
|
75
|
+
} \
|
76
|
+
\
|
77
|
+
unsigned int num_channels; \
|
78
|
+
unsigned int sample_rate; \
|
79
|
+
dr ## FORMAT ## _uint64 total_frames; \
|
80
|
+
\
|
81
|
+
FRAME_TYPE * frames = dr ## FORMAT ## _open_memory_and_read_pcm_frames_ ## CODE (\
|
82
|
+
StringValuePtr(str),\
|
83
|
+
RSTRING_LEN(str),\
|
84
|
+
&num_channels,\
|
85
|
+
&sample_rate,\
|
86
|
+
&total_frames,\
|
87
|
+
NULL\
|
88
|
+
);\
|
89
|
+
\
|
90
|
+
if (frames == NULL) {\
|
91
|
+
return Qnil;\
|
92
|
+
}\
|
93
|
+
\
|
94
|
+
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*num_channels*total_frames);\
|
95
|
+
dr ## FORMAT ## _free(frames, NULL);\
|
96
|
+
VALUE ret = rb_ary_new();\
|
97
|
+
rb_ary_push(ret, ret_str);\
|
98
|
+
rb_ary_push(ret, INT2NUM(sample_rate));\
|
99
|
+
rb_ary_push(ret, INT2NUM(num_channels));\
|
100
|
+
rb_ary_push(ret, INT2NUM(total_frames));\
|
101
|
+
return ret;\
|
102
|
+
}
|
103
|
+
|
104
|
+
#define OPEN_MP3_MEMORY(FRAME_TYPE, CODE) \
|
105
|
+
static VALUE rb_drmp3_open_memory_and_read_pcm_frames_ ## CODE (VALUE mod, VALUE str) { \
|
106
|
+
if (TYPE(str) != T_STRING) { \
|
107
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Memory must be a string"); \
|
108
|
+
} \
|
109
|
+
\
|
110
|
+
drmp3_uint64 total_frames; \
|
111
|
+
\
|
112
|
+
drmp3_config config;\
|
113
|
+
FRAME_TYPE * frames = drmp3_open_memory_and_read_pcm_frames_ ## CODE (\
|
114
|
+
StringValuePtr(str),\
|
115
|
+
RSTRING_LEN(str),\
|
116
|
+
&config,\
|
117
|
+
&total_frames,\
|
118
|
+
NULL\
|
119
|
+
);\
|
120
|
+
\
|
121
|
+
if (frames == NULL) {\
|
122
|
+
return Qnil;\
|
123
|
+
}\
|
124
|
+
\
|
125
|
+
VALUE ret_str = rb_str_new((char*)frames, sizeof(FRAME_TYPE)*config.channels*total_frames);\
|
126
|
+
drmp3_free(frames, NULL);\
|
127
|
+
VALUE ret = rb_ary_new();\
|
128
|
+
rb_ary_push(ret, ret_str);\
|
129
|
+
rb_ary_push(ret, INT2NUM(config.sampleRate));\
|
130
|
+
rb_ary_push(ret, INT2NUM(config.channels));\
|
131
|
+
rb_ary_push(ret, INT2NUM(total_frames));\
|
132
|
+
return ret;\
|
133
|
+
}
|
134
|
+
|
135
|
+
static VALUE rb_stb_vorbis_decode_filename_s16 (VALUE mod, VALUE filename) {
|
136
|
+
if (TYPE(filename) != T_STRING) {
|
137
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Filename must be a string");
|
138
|
+
}
|
139
|
+
|
140
|
+
int num_channels;
|
141
|
+
int sample_rate;
|
142
|
+
int64_t total_frames;
|
143
|
+
|
144
|
+
int16_t *output;
|
145
|
+
|
146
|
+
total_frames = stb_vorbis_decode_filename (
|
147
|
+
StringValueCStr(filename),
|
148
|
+
&num_channels,
|
149
|
+
&sample_rate,
|
150
|
+
&output
|
151
|
+
);
|
152
|
+
|
153
|
+
if (total_frames < 0) {
|
154
|
+
return Qnil;
|
155
|
+
}
|
156
|
+
|
157
|
+
VALUE ret_str = rb_str_new((char*)output, sizeof(int16_t)*num_channels*total_frames);
|
158
|
+
free(output);
|
159
|
+
VALUE ret = rb_ary_new();
|
160
|
+
rb_ary_push(ret, ret_str);
|
161
|
+
rb_ary_push(ret, INT2NUM(sample_rate));
|
162
|
+
rb_ary_push(ret, INT2NUM(num_channels));
|
163
|
+
rb_ary_push(ret, INT2NUM(total_frames));
|
164
|
+
return ret;
|
165
|
+
}
|
166
|
+
|
167
|
+
static VALUE rb_stb_vorbis_decode_memory_s16(VALUE mod, VALUE str) {
|
168
|
+
if (TYPE(str) != T_STRING) {
|
169
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Memory storage must be a string");
|
170
|
+
}
|
171
|
+
|
172
|
+
int num_channels;
|
173
|
+
int sample_rate;
|
174
|
+
int64_t total_frames;
|
175
|
+
|
176
|
+
int16_t *output;
|
177
|
+
|
178
|
+
total_frames = stb_vorbis_decode_memory(
|
179
|
+
(uint8*)StringValuePtr(str),
|
180
|
+
RSTRING_LEN(str),
|
181
|
+
&num_channels,
|
182
|
+
&sample_rate,
|
183
|
+
&output
|
184
|
+
);
|
185
|
+
|
186
|
+
if (total_frames < 0) {
|
187
|
+
return Qnil;
|
188
|
+
}
|
189
|
+
|
190
|
+
VALUE ret_str = rb_str_new((char*)output, sizeof(int16_t)*num_channels*total_frames);
|
191
|
+
free(output);
|
192
|
+
VALUE ret = rb_ary_new();
|
193
|
+
rb_ary_push(ret, ret_str);
|
194
|
+
rb_ary_push(ret, INT2NUM(sample_rate));
|
195
|
+
rb_ary_push(ret, INT2NUM(num_channels));
|
196
|
+
rb_ary_push(ret, INT2NUM(total_frames));
|
197
|
+
return ret;
|
198
|
+
}
|
199
|
+
|
200
|
+
OPEN_FILE(wav, int16_t, s16)
|
201
|
+
OPEN_FILE(wav, int32_t, s32)
|
202
|
+
OPEN_FILE(wav, float, f32)
|
203
|
+
|
204
|
+
OPEN_MP3_FILE(int16_t, s16)
|
205
|
+
OPEN_MP3_FILE(float, f32)
|
206
|
+
|
207
|
+
OPEN_FILE(flac, int16_t, s16)
|
208
|
+
OPEN_FILE(flac, int32_t, s32)
|
209
|
+
OPEN_FILE(flac, float, f32)
|
210
|
+
|
211
|
+
OPEN_MEMORY(wav, int16_t, s16)
|
212
|
+
OPEN_MEMORY(wav, int32_t, s32)
|
213
|
+
OPEN_MEMORY(wav, float, f32)
|
214
|
+
|
215
|
+
OPEN_MP3_MEMORY(int16_t, s16)
|
216
|
+
OPEN_MP3_MEMORY(float, f32)
|
217
|
+
|
218
|
+
OPEN_MEMORY(flac, int16_t, s16)
|
219
|
+
OPEN_MEMORY(flac, int32_t, s32)
|
220
|
+
OPEN_MEMORY(flac, float, f32)
|
221
|
+
|
222
|
+
void define_read_functions_under(VALUE mod) {
|
223
|
+
rb_define_module_function(mod, "wav_read_file_s16", &rb_drwav_open_file_and_read_pcm_frames_s16, 1);
|
224
|
+
rb_define_module_function(mod, "wav_read_file_s32", &rb_drwav_open_file_and_read_pcm_frames_s32, 1);
|
225
|
+
rb_define_module_function(mod, "wav_read_file_f32", &rb_drwav_open_file_and_read_pcm_frames_f32, 1);
|
226
|
+
rb_define_module_function(mod, "mp3_read_file_s16", rb_drmp3_open_file_and_read_pcm_frames_s16, 1);
|
227
|
+
rb_define_module_function(mod, "mp3_read_file_f32", rb_drmp3_open_file_and_read_pcm_frames_f32, 1);
|
228
|
+
rb_define_module_function(mod, "flac_read_file_s16", &rb_drflac_open_file_and_read_pcm_frames_s16, 1);
|
229
|
+
rb_define_module_function(mod, "flac_read_file_s32", &rb_drflac_open_file_and_read_pcm_frames_s32, 1);
|
230
|
+
rb_define_module_function(mod, "flac_read_file_f32", &rb_drflac_open_file_and_read_pcm_frames_f32, 1);
|
231
|
+
rb_define_module_function(mod, "vorbis_read_file_s16", &rb_stb_vorbis_decode_filename_s16, 1);
|
232
|
+
rb_define_module_function(mod, "wav_read_s16", &rb_drwav_open_memory_and_read_pcm_frames_s16, 1);
|
233
|
+
rb_define_module_function(mod, "wav_read_s32", &rb_drwav_open_memory_and_read_pcm_frames_s32, 1);
|
234
|
+
rb_define_module_function(mod, "wav_read_f32", &rb_drwav_open_memory_and_read_pcm_frames_f32, 1);
|
235
|
+
rb_define_module_function(mod, "mp3_read_s16", rb_drmp3_open_memory_and_read_pcm_frames_s16, 1);
|
236
|
+
rb_define_module_function(mod, "mp3_read_f32", rb_drmp3_open_memory_and_read_pcm_frames_f32, 1);
|
237
|
+
rb_define_module_function(mod, "flac_read_s16", &rb_drflac_open_memory_and_read_pcm_frames_s16, 1);
|
238
|
+
rb_define_module_function(mod, "flac_read_s32", &rb_drflac_open_memory_and_read_pcm_frames_s32, 1);
|
239
|
+
rb_define_module_function(mod, "flac_read_f32", &rb_drflac_open_memory_and_read_pcm_frames_f32, 1);
|
240
|
+
rb_define_module_function(mod, "vorbis_file_s16", &rb_stb_vorbis_decode_memory_s16, 1);
|
241
|
+
}
|
data/lib/miniaudio.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miniaudio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Razuvaev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Miniaudio library (https://github.com/mackron/miniaudio) Ruby wrapper
|
14
14
|
email: team@orlando-labs.com
|
@@ -17,10 +17,12 @@ extensions:
|
|
17
17
|
- ext/miniaudio/extconf.rb
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- ext/miniaudio/convert_functions.h
|
20
21
|
- ext/miniaudio/extconf.rb
|
21
22
|
- ext/miniaudio/miniaudio/extras/stb_vorbis.c
|
22
23
|
- ext/miniaudio/miniaudio/miniaudio.h
|
23
24
|
- ext/miniaudio/rb-miniaudio.c
|
25
|
+
- ext/miniaudio/read_functions.h
|
24
26
|
- lib/miniaudio.rb
|
25
27
|
homepage: https://github.com/orlando-labs/rb-miniaudio
|
26
28
|
licenses:
|
@@ -41,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
41
43
|
- !ruby/object:Gem::Version
|
42
44
|
version: '0'
|
43
45
|
requirements: []
|
44
|
-
rubygems_version: 3.
|
46
|
+
rubygems_version: 3.2.3
|
45
47
|
signing_key:
|
46
48
|
specification_version: 4
|
47
49
|
summary: Miniaudio library Ruby wrapper
|