miniaudio 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 101569a03086e063ac575b31a171302e04aa6a4dbf10d0a7e52c5190a8f2d332
4
- data.tar.gz: 63507f3d862f48b0962d8a35ddf1dcb63d783250644deb40241e042ab513994c
3
+ metadata.gz: 306f78eb852bb174b8633fc9ad08aa6326781cd093dbd73273d08c443abc6dc7
4
+ data.tar.gz: cc91095d14079ae4a07ab781aadc9b3d1ba1a56fef79d6a9004dc30b9287ce77
5
5
  SHA512:
6
- metadata.gz: b348d86e3c0d3bd22c624fdc21a673a7e64c225ee653d30aec594dd7cfa819d52398957b8b58dee110b710a48317bdb5efde63fef1778db6cb2b779904f2db0e
7
- data.tar.gz: 5d45d419e63ef7690db2780ec1c0894d9d6df92913ef3ed17ef3637c405d0c4b395a8216906472a839d5143434e15f1c703675ea2c2dd7232b3abe67fc063623
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
- #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)*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 mod = rb_const_get(rb_cObject, rb_intern("Miniaudio"));
224
- rb_define_module_function(mod, "wav_read_file_s16", &rb_drwav_open_file_and_read_pcm_frames_s16, 1);
225
- rb_define_module_function(mod, "wav_read_file_s32", &rb_drwav_open_file_and_read_pcm_frames_s32, 1);
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
@@ -1,5 +1,7 @@
1
1
  module Miniaudio
2
2
  VERSION = '0.1.0'
3
+
4
+ FRAME_FORMATS = %i[u8 s16 s24 s32 f32]
3
5
  end
4
6
 
5
7
  require 'miniaudio/miniaudio'
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.2.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-02 00:00:00.000000000 Z
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.1.4
46
+ rubygems_version: 3.2.3
45
47
  signing_key:
46
48
  specification_version: 4
47
49
  summary: Miniaudio library Ruby wrapper