react-native-audio-api 0.7.1-nightly-5a218c6-20250810 → 0.7.1-nightly-968a0e5-20250812

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.
Files changed (62) hide show
  1. package/RNAudioAPI.podspec +30 -7
  2. package/android/src/main/cpp/audioapi/CMakeLists.txt +22 -1
  3. package/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp +81 -63
  4. package/common/cpp/audioapi/core/utils/AudioDecoder.h +54 -29
  5. package/common/cpp/audioapi/external/arm64-v8a/libogg.a +0 -0
  6. package/common/cpp/audioapi/external/arm64-v8a/libopus.a +0 -0
  7. package/common/cpp/audioapi/external/arm64-v8a/libopusfile.a +0 -0
  8. package/common/cpp/audioapi/external/arm64-v8a/libvorbis.a +0 -0
  9. package/common/cpp/audioapi/external/arm64-v8a/libvorbisenc.a +0 -0
  10. package/common/cpp/audioapi/external/arm64-v8a/libvorbisfile.a +0 -0
  11. package/common/cpp/audioapi/external/armeabi-v7a/libogg.a +0 -0
  12. package/common/cpp/audioapi/external/armeabi-v7a/libopus.a +0 -0
  13. package/common/cpp/audioapi/external/armeabi-v7a/libopusfile.a +0 -0
  14. package/common/cpp/audioapi/external/armeabi-v7a/libvorbis.a +0 -0
  15. package/common/cpp/audioapi/external/armeabi-v7a/libvorbisenc.a +0 -0
  16. package/common/cpp/audioapi/external/armeabi-v7a/libvorbisfile.a +0 -0
  17. package/common/cpp/audioapi/external/include/ogg/config_types.h +26 -0
  18. package/common/cpp/audioapi/external/include/ogg/config_types.h.in +26 -0
  19. package/common/cpp/audioapi/external/include/ogg/ogg.h +212 -0
  20. package/common/cpp/audioapi/external/include/ogg/os_types.h +157 -0
  21. package/common/cpp/audioapi/external/include/opus/opus.h +1286 -0
  22. package/common/cpp/audioapi/external/include/opus/opus_custom.h +390 -0
  23. package/common/cpp/audioapi/external/include/opus/opus_defines.h +896 -0
  24. package/common/cpp/audioapi/external/include/opus/opus_multistream.h +728 -0
  25. package/common/cpp/audioapi/external/include/opus/opus_projection.h +621 -0
  26. package/common/cpp/audioapi/external/include/opus/opus_types.h +170 -0
  27. package/common/cpp/audioapi/external/include/opusfile/opusfile.h +2151 -0
  28. package/common/cpp/audioapi/external/include/vorbis/codec.h +241 -0
  29. package/common/cpp/audioapi/external/include/vorbis/vorbisenc.h +446 -0
  30. package/common/cpp/audioapi/external/include/vorbis/vorbisfile.h +226 -0
  31. package/common/cpp/audioapi/external/iphoneos/libogg.a +0 -0
  32. package/common/cpp/audioapi/external/iphoneos/libopus.a +0 -0
  33. package/common/cpp/audioapi/external/iphoneos/libopusfile.a +0 -0
  34. package/common/cpp/audioapi/external/iphoneos/libvorbis.a +0 -0
  35. package/common/cpp/audioapi/external/iphoneos/libvorbisenc.a +0 -0
  36. package/common/cpp/audioapi/external/iphoneos/libvorbisfile.a +0 -0
  37. package/common/cpp/audioapi/external/iphonesimulator/libogg.a +0 -0
  38. package/common/cpp/audioapi/external/iphonesimulator/libopus.a +0 -0
  39. package/common/cpp/audioapi/external/iphonesimulator/libopusfile.a +0 -0
  40. package/common/cpp/audioapi/external/iphonesimulator/libvorbis.a +0 -0
  41. package/common/cpp/audioapi/external/iphonesimulator/libvorbisenc.a +0 -0
  42. package/common/cpp/audioapi/external/iphonesimulator/libvorbisfile.a +0 -0
  43. package/common/cpp/audioapi/external/x86/libogg.a +0 -0
  44. package/common/cpp/audioapi/external/x86/libopus.a +0 -0
  45. package/common/cpp/audioapi/external/x86/libopusfile.a +0 -0
  46. package/common/cpp/audioapi/external/x86/libvorbis.a +0 -0
  47. package/common/cpp/audioapi/external/x86/libvorbisenc.a +0 -0
  48. package/common/cpp/audioapi/external/x86/libvorbisfile.a +0 -0
  49. package/common/cpp/audioapi/external/x86_64/libogg.a +0 -0
  50. package/common/cpp/audioapi/external/x86_64/libopus.a +0 -0
  51. package/common/cpp/audioapi/external/x86_64/libopusfile.a +0 -0
  52. package/common/cpp/audioapi/external/x86_64/libvorbis.a +0 -0
  53. package/common/cpp/audioapi/external/x86_64/libvorbisenc.a +0 -0
  54. package/common/cpp/audioapi/external/x86_64/libvorbisfile.a +0 -0
  55. package/common/cpp/audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.c +623 -0
  56. package/common/cpp/audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h +71 -0
  57. package/common/cpp/audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.c +574 -0
  58. package/common/cpp/audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.h +41 -0
  59. package/common/cpp/test/CMakeLists.txt +7 -0
  60. package/common/cpp/test/RunTests.sh +3 -8
  61. package/ios/audioapi/ios/core/AudioDecoder.mm +62 -51
  62. package/package.json +1 -1
@@ -0,0 +1,623 @@
1
+ #ifndef miniaudio_libopus_c
2
+ #define miniaudio_libopus_c
3
+
4
+ #include <audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h>
5
+
6
+ #if !defined(MA_NO_LIBOPUS)
7
+ #include <audioapi/external/include/opusfile/opusfile.h>
8
+ #endif
9
+
10
+ #include <assert.h>
11
+ #include <string.h> /* For memset(). */
12
+
13
+ static ma_result ma_libopus_ds_read(
14
+ ma_data_source *pDataSource,
15
+ void *pFramesOut,
16
+ ma_uint64 frameCount,
17
+ ma_uint64 *pFramesRead) {
18
+ return ma_libopus_read_pcm_frames(
19
+ (ma_libopus *)pDataSource, pFramesOut, frameCount, pFramesRead);
20
+ }
21
+
22
+ static ma_result ma_libopus_ds_seek(
23
+ ma_data_source *pDataSource,
24
+ ma_uint64 frameIndex) {
25
+ return ma_libopus_seek_to_pcm_frame((ma_libopus *)pDataSource, frameIndex);
26
+ }
27
+
28
+ static ma_result ma_libopus_ds_get_data_format(
29
+ ma_data_source *pDataSource,
30
+ ma_format *pFormat,
31
+ ma_uint32 *pChannels,
32
+ ma_uint32 *pSampleRate,
33
+ ma_channel *pChannelMap,
34
+ size_t channelMapCap) {
35
+ return ma_libopus_get_data_format(
36
+ (ma_libopus *)pDataSource,
37
+ pFormat,
38
+ pChannels,
39
+ pSampleRate,
40
+ pChannelMap,
41
+ channelMapCap);
42
+ }
43
+
44
+ static ma_result ma_libopus_ds_get_cursor(
45
+ ma_data_source *pDataSource,
46
+ ma_uint64 *pCursor) {
47
+ return ma_libopus_get_cursor_in_pcm_frames(
48
+ (ma_libopus *)pDataSource, pCursor);
49
+ }
50
+
51
+ static ma_result ma_libopus_ds_get_length(
52
+ ma_data_source *pDataSource,
53
+ ma_uint64 *pLength) {
54
+ return ma_libopus_get_length_in_pcm_frames(
55
+ (ma_libopus *)pDataSource, pLength);
56
+ }
57
+
58
+ static ma_data_source_vtable g_ma_libopus_ds_vtable = {
59
+ ma_libopus_ds_read,
60
+ ma_libopus_ds_seek,
61
+ ma_libopus_ds_get_data_format,
62
+ ma_libopus_ds_get_cursor,
63
+ ma_libopus_ds_get_length,
64
+ NULL, /* onSetLooping */
65
+ 0 /* flags */
66
+ };
67
+
68
+ #if !defined(MA_NO_LIBOPUS)
69
+ static int ma_libopus_of_callback__read(
70
+ void *pUserData,
71
+ unsigned char *pBufferOut,
72
+ int bytesToRead) {
73
+ ma_libopus *pOpus = (ma_libopus *)pUserData;
74
+ ma_result result;
75
+ size_t bytesRead;
76
+
77
+ result = pOpus->onRead(
78
+ pOpus->pReadSeekTellUserData,
79
+ (void *)pBufferOut,
80
+ bytesToRead,
81
+ &bytesRead);
82
+
83
+ if (result != MA_SUCCESS) {
84
+ return -1;
85
+ }
86
+
87
+ return (int)bytesRead;
88
+ }
89
+
90
+ static int
91
+ ma_libopus_of_callback__seek(void *pUserData, ogg_int64_t offset, int whence) {
92
+ ma_libopus *pOpus = (ma_libopus *)pUserData;
93
+ ma_result result;
94
+ ma_seek_origin origin;
95
+
96
+ if (whence == SEEK_SET) {
97
+ origin = ma_seek_origin_start;
98
+ } else if (whence == SEEK_END) {
99
+ origin = ma_seek_origin_end;
100
+ } else {
101
+ origin = ma_seek_origin_current;
102
+ }
103
+
104
+ result = pOpus->onSeek(pOpus->pReadSeekTellUserData, offset, origin);
105
+ if (result != MA_SUCCESS) {
106
+ return -1;
107
+ }
108
+
109
+ return 0;
110
+ }
111
+
112
+ static opus_int64 ma_libopus_of_callback__tell(void *pUserData) {
113
+ ma_libopus *pOpus = (ma_libopus *)pUserData;
114
+ ma_result result;
115
+ ma_int64 cursor;
116
+
117
+ if (pOpus->onTell == NULL) {
118
+ return -1;
119
+ }
120
+
121
+ result = pOpus->onTell(pOpus->pReadSeekTellUserData, &cursor);
122
+ if (result != MA_SUCCESS) {
123
+ return -1;
124
+ }
125
+
126
+ return cursor;
127
+ }
128
+ #endif
129
+
130
+ static ma_result ma_libopus_init_internal(
131
+ const ma_decoding_backend_config *pConfig,
132
+ ma_libopus *pOpus) {
133
+ ma_result result;
134
+ ma_data_source_config dataSourceConfig;
135
+
136
+ if (pOpus == NULL) {
137
+ return MA_INVALID_ARGS;
138
+ }
139
+
140
+ memset(pOpus, 0, sizeof(*pOpus));
141
+ pOpus->format = ma_format_f32; /* f32 by default. */
142
+
143
+ if (pConfig != NULL &&
144
+ (pConfig->preferredFormat == ma_format_f32 ||
145
+ pConfig->preferredFormat == ma_format_s16)) {
146
+ pOpus->format = pConfig->preferredFormat;
147
+ } else {
148
+ /* Getting here means something other than f32 and s16 was specified. Just
149
+ * leave this unset to use the default format. */
150
+ }
151
+
152
+ dataSourceConfig = ma_data_source_config_init();
153
+ dataSourceConfig.vtable = &g_ma_libopus_ds_vtable;
154
+
155
+ result = ma_data_source_init(&dataSourceConfig, &pOpus->ds);
156
+ if (result != MA_SUCCESS) {
157
+ return result; /* Failed to initialize the base data source. */
158
+ }
159
+
160
+ return MA_SUCCESS;
161
+ }
162
+
163
+ MA_API ma_result ma_libopus_init(
164
+ ma_read_proc onRead,
165
+ ma_seek_proc onSeek,
166
+ ma_tell_proc onTell,
167
+ void *pReadSeekTellUserData,
168
+ const ma_decoding_backend_config *pConfig,
169
+ const ma_allocation_callbacks *pAllocationCallbacks,
170
+ ma_libopus *pOpus) {
171
+ ma_result result;
172
+
173
+ (void)pAllocationCallbacks; /* Can't seem to find a way to configure memory
174
+ allocations in libopus. */
175
+
176
+ result = ma_libopus_init_internal(pConfig, pOpus);
177
+ if (result != MA_SUCCESS) {
178
+ return result;
179
+ }
180
+
181
+ if (onRead == NULL || onSeek == NULL) {
182
+ return MA_INVALID_ARGS; /* onRead and onSeek are mandatory. */
183
+ }
184
+
185
+ pOpus->onRead = onRead;
186
+ pOpus->onSeek = onSeek;
187
+ pOpus->onTell = onTell;
188
+ pOpus->pReadSeekTellUserData = pReadSeekTellUserData;
189
+
190
+ #if !defined(MA_NO_LIBOPUS)
191
+ {
192
+ int libopusResult;
193
+ OpusFileCallbacks libopusCallbacks;
194
+
195
+ /* We can now initialize the Opus decoder. This must be done after we've set
196
+ * up the callbacks. */
197
+ libopusCallbacks.read = ma_libopus_of_callback__read;
198
+ libopusCallbacks.seek = ma_libopus_of_callback__seek;
199
+ libopusCallbacks.close = NULL;
200
+ libopusCallbacks.tell = ma_libopus_of_callback__tell;
201
+
202
+ pOpus->of =
203
+ op_open_callbacks(pOpus, &libopusCallbacks, NULL, 0, &libopusResult);
204
+ if (pOpus->of == NULL) {
205
+ return MA_INVALID_FILE;
206
+ }
207
+
208
+ return MA_SUCCESS;
209
+ }
210
+ #else
211
+ {
212
+ /* libopus is disabled. */
213
+ return MA_NOT_IMPLEMENTED;
214
+ }
215
+ #endif
216
+ }
217
+
218
+ MA_API ma_result ma_libopus_init_file(
219
+ const char *pFilePath,
220
+ const ma_decoding_backend_config *pConfig,
221
+ const ma_allocation_callbacks *pAllocationCallbacks,
222
+ ma_libopus *pOpus) {
223
+ ma_result result;
224
+
225
+ (void)pAllocationCallbacks; /* Can't seem to find a way to configure memory
226
+ allocations in libopus. */
227
+
228
+ result = ma_libopus_init_internal(pConfig, pOpus);
229
+ if (result != MA_SUCCESS) {
230
+ return result;
231
+ }
232
+
233
+ #if !defined(MA_NO_LIBOPUS)
234
+ {
235
+ int libopusResult;
236
+
237
+ pOpus->of = op_open_file(pFilePath, &libopusResult);
238
+ if (pOpus->of == NULL) {
239
+ return MA_INVALID_FILE;
240
+ }
241
+
242
+ return MA_SUCCESS;
243
+ }
244
+ #else
245
+ {
246
+ /* libopus is disabled. */
247
+ (void)pFilePath;
248
+ return MA_NOT_IMPLEMENTED;
249
+ }
250
+ #endif
251
+ }
252
+
253
+ MA_API void ma_libopus_uninit(
254
+ ma_libopus *pOpus,
255
+ const ma_allocation_callbacks *pAllocationCallbacks) {
256
+ if (pOpus == NULL) {
257
+ return;
258
+ }
259
+
260
+ (void)pAllocationCallbacks;
261
+
262
+ #if !defined(MA_NO_LIBOPUS)
263
+ {
264
+ op_free((OggOpusFile *)pOpus->of);
265
+ }
266
+ #else
267
+ {
268
+ /* libopus is disabled. Should never hit this since initialization would
269
+ * have failed. */
270
+ assert(MA_FALSE);
271
+ }
272
+ #endif
273
+
274
+ ma_data_source_uninit(&pOpus->ds);
275
+ }
276
+
277
+ MA_API ma_result ma_libopus_read_pcm_frames(
278
+ ma_libopus *pOpus,
279
+ void *pFramesOut,
280
+ ma_uint64 frameCount,
281
+ ma_uint64 *pFramesRead) {
282
+ if (pFramesRead != NULL) {
283
+ *pFramesRead = 0;
284
+ }
285
+
286
+ if (frameCount == 0) {
287
+ return MA_INVALID_ARGS;
288
+ }
289
+
290
+ if (pOpus == NULL) {
291
+ return MA_INVALID_ARGS;
292
+ }
293
+
294
+ #if !defined(MA_NO_LIBOPUS)
295
+ {
296
+ /* We always use floating point format. */
297
+ ma_result result = MA_SUCCESS; /* Must be initialized to MA_SUCCESS. */
298
+ ma_uint64 totalFramesRead;
299
+ ma_format format;
300
+ ma_uint32 channels;
301
+
302
+ ma_libopus_get_data_format(pOpus, &format, &channels, NULL, NULL, 0);
303
+
304
+ totalFramesRead = 0;
305
+ while (totalFramesRead < frameCount) {
306
+ long libopusResult;
307
+ ma_uint64 framesToRead;
308
+ ma_uint64 framesRemaining;
309
+
310
+ framesRemaining = (frameCount - totalFramesRead);
311
+ framesToRead = 1024;
312
+ if (framesToRead > framesRemaining) {
313
+ framesToRead = framesRemaining;
314
+ }
315
+
316
+ if (format == ma_format_f32) {
317
+ libopusResult = op_read_float(
318
+ (OggOpusFile *)pOpus->of,
319
+ (float *)ma_offset_pcm_frames_ptr(
320
+ pFramesOut, totalFramesRead, format, channels),
321
+ (int)(framesToRead * channels),
322
+ NULL);
323
+ } else {
324
+ libopusResult = op_read(
325
+ (OggOpusFile *)pOpus->of,
326
+ (opus_int16 *)ma_offset_pcm_frames_ptr(
327
+ pFramesOut, totalFramesRead, format, channels),
328
+ (int)(framesToRead * channels),
329
+ NULL);
330
+ }
331
+
332
+ if (libopusResult < 0) {
333
+ result = MA_ERROR; /* Error while decoding. */
334
+ break;
335
+ } else {
336
+ totalFramesRead += libopusResult;
337
+
338
+ if (libopusResult == 0) {
339
+ result = MA_AT_END;
340
+ break;
341
+ }
342
+ }
343
+ }
344
+
345
+ if (pFramesRead != NULL) {
346
+ *pFramesRead = totalFramesRead;
347
+ }
348
+
349
+ if (result == MA_SUCCESS && totalFramesRead == 0) {
350
+ result = MA_AT_END;
351
+ }
352
+
353
+ return result;
354
+ }
355
+ #else
356
+ {
357
+ /* libopus is disabled. Should never hit this since initialization would
358
+ * have failed. */
359
+ assert(MA_FALSE);
360
+
361
+ (void)pFramesOut;
362
+ (void)frameCount;
363
+ (void)pFramesRead;
364
+
365
+ return MA_NOT_IMPLEMENTED;
366
+ }
367
+ #endif
368
+ }
369
+
370
+ MA_API ma_result
371
+ ma_libopus_seek_to_pcm_frame(ma_libopus *pOpus, ma_uint64 frameIndex) {
372
+ if (pOpus == NULL) {
373
+ return MA_INVALID_ARGS;
374
+ }
375
+
376
+ #if !defined(MA_NO_LIBOPUS)
377
+ {
378
+ int libopusResult =
379
+ op_pcm_seek((OggOpusFile *)pOpus->of, (ogg_int64_t)frameIndex);
380
+ if (libopusResult != 0) {
381
+ if (libopusResult == OP_ENOSEEK) {
382
+ return MA_INVALID_OPERATION; /* Not seekable. */
383
+ } else if (libopusResult == OP_EINVAL) {
384
+ return MA_INVALID_ARGS;
385
+ } else {
386
+ return MA_ERROR;
387
+ }
388
+ }
389
+
390
+ return MA_SUCCESS;
391
+ }
392
+ #else
393
+ {
394
+ /* libopus is disabled. Should never hit this since initialization would
395
+ * have failed. */
396
+ assert(MA_FALSE);
397
+
398
+ (void)frameIndex;
399
+
400
+ return MA_NOT_IMPLEMENTED;
401
+ }
402
+ #endif
403
+ }
404
+
405
+ MA_API ma_result ma_libopus_get_data_format(
406
+ ma_libopus *pOpus,
407
+ ma_format *pFormat,
408
+ ma_uint32 *pChannels,
409
+ ma_uint32 *pSampleRate,
410
+ ma_channel *pChannelMap,
411
+ size_t channelMapCap) {
412
+ /* Defaults for safety. */
413
+ if (pFormat != NULL) {
414
+ *pFormat = ma_format_unknown;
415
+ }
416
+ if (pChannels != NULL) {
417
+ *pChannels = 0;
418
+ }
419
+ if (pSampleRate != NULL) {
420
+ *pSampleRate = 0;
421
+ }
422
+ if (pChannelMap != NULL) {
423
+ memset(pChannelMap, 0, sizeof(*pChannelMap) * channelMapCap);
424
+ }
425
+
426
+ if (pOpus == NULL) {
427
+ return MA_INVALID_OPERATION;
428
+ }
429
+
430
+ if (pFormat != NULL) {
431
+ *pFormat = pOpus->format;
432
+ }
433
+
434
+ #if !defined(MA_NO_LIBOPUS)
435
+ {
436
+ ma_uint32 channels = op_channel_count((OggOpusFile *)pOpus->of, -1);
437
+
438
+ if (pChannels != NULL) {
439
+ *pChannels = channels;
440
+ }
441
+
442
+ if (pSampleRate != NULL) {
443
+ *pSampleRate = 48000;
444
+ }
445
+
446
+ if (pChannelMap != NULL) {
447
+ ma_channel_map_init_standard(
448
+ ma_standard_channel_map_vorbis, pChannelMap, channelMapCap, channels);
449
+ }
450
+
451
+ return MA_SUCCESS;
452
+ }
453
+ #else
454
+ {
455
+ /* libopus is disabled. Should never hit this since initialization would
456
+ * have failed. */
457
+ assert(MA_FALSE);
458
+ return MA_NOT_IMPLEMENTED;
459
+ }
460
+ #endif
461
+ }
462
+
463
+ MA_API ma_result
464
+ ma_libopus_get_cursor_in_pcm_frames(ma_libopus *pOpus, ma_uint64 *pCursor) {
465
+ if (pCursor == NULL) {
466
+ return MA_INVALID_ARGS;
467
+ }
468
+
469
+ *pCursor = 0; /* Safety. */
470
+
471
+ if (pOpus == NULL) {
472
+ return MA_INVALID_ARGS;
473
+ }
474
+
475
+ #if !defined(MA_NO_LIBOPUS)
476
+ {
477
+ ogg_int64_t offset = op_pcm_tell((OggOpusFile *)pOpus->of);
478
+ if (offset < 0) {
479
+ return MA_INVALID_FILE;
480
+ }
481
+
482
+ *pCursor = (ma_uint64)offset;
483
+
484
+ return MA_SUCCESS;
485
+ }
486
+ #else
487
+ {
488
+ /* libopus is disabled. Should never hit this since initialization would
489
+ * have failed. */
490
+ assert(MA_FALSE);
491
+ return MA_NOT_IMPLEMENTED;
492
+ }
493
+ #endif
494
+ }
495
+
496
+ MA_API ma_result
497
+ ma_libopus_get_length_in_pcm_frames(ma_libopus *pOpus, ma_uint64 *pLength) {
498
+ if (pLength == NULL) {
499
+ return MA_INVALID_ARGS;
500
+ }
501
+
502
+ *pLength = 0; /* Safety. */
503
+
504
+ if (pOpus == NULL) {
505
+ return MA_INVALID_ARGS;
506
+ }
507
+
508
+ #if !defined(MA_NO_LIBOPUS)
509
+ {
510
+ ogg_int64_t length = op_pcm_total((OggOpusFile *)pOpus->of, -1);
511
+ if (length < 0) {
512
+ return MA_ERROR;
513
+ }
514
+
515
+ *pLength = (ma_uint64)length;
516
+
517
+ return MA_SUCCESS;
518
+ }
519
+ #else
520
+ {
521
+ /* libopus is disabled. Should never hit this since initialization would
522
+ * have failed. */
523
+ assert(MA_FALSE);
524
+ return MA_NOT_IMPLEMENTED;
525
+ }
526
+ #endif
527
+ }
528
+
529
+ /*
530
+ The code below defines the vtable that you'll plug into your `ma_decoder_config`
531
+ object.
532
+ */
533
+ #if !defined(MA_NO_LIBOPUS)
534
+ static ma_result ma_decoding_backend_init__libopus(
535
+ void *pUserData,
536
+ ma_read_proc onRead,
537
+ ma_seek_proc onSeek,
538
+ ma_tell_proc onTell,
539
+ void *pReadSeekTellUserData,
540
+ const ma_decoding_backend_config *pConfig,
541
+ const ma_allocation_callbacks *pAllocationCallbacks,
542
+ ma_data_source **ppBackend) {
543
+ ma_result result;
544
+ ma_libopus *pOpus;
545
+
546
+ (void)pUserData;
547
+
548
+ pOpus = (ma_libopus *)ma_malloc(sizeof(*pOpus), pAllocationCallbacks);
549
+ if (pOpus == NULL) {
550
+ return MA_OUT_OF_MEMORY;
551
+ }
552
+
553
+ result = ma_libopus_init(
554
+ onRead,
555
+ onSeek,
556
+ onTell,
557
+ pReadSeekTellUserData,
558
+ pConfig,
559
+ pAllocationCallbacks,
560
+ pOpus);
561
+ if (result != MA_SUCCESS) {
562
+ ma_free(pOpus, pAllocationCallbacks);
563
+ return result;
564
+ }
565
+
566
+ *ppBackend = pOpus;
567
+
568
+ return MA_SUCCESS;
569
+ }
570
+
571
+ static ma_result ma_decoding_backend_init_file__libopus(
572
+ void *pUserData,
573
+ const char *pFilePath,
574
+ const ma_decoding_backend_config *pConfig,
575
+ const ma_allocation_callbacks *pAllocationCallbacks,
576
+ ma_data_source **ppBackend) {
577
+ ma_result result;
578
+ ma_libopus *pOpus;
579
+
580
+ (void)pUserData;
581
+
582
+ pOpus = (ma_libopus *)ma_malloc(sizeof(*pOpus), pAllocationCallbacks);
583
+ if (pOpus == NULL) {
584
+ return MA_OUT_OF_MEMORY;
585
+ }
586
+
587
+ result =
588
+ ma_libopus_init_file(pFilePath, pConfig, pAllocationCallbacks, pOpus);
589
+ if (result != MA_SUCCESS) {
590
+ ma_free(pOpus, pAllocationCallbacks);
591
+ return result;
592
+ }
593
+
594
+ *ppBackend = pOpus;
595
+
596
+ return MA_SUCCESS;
597
+ }
598
+
599
+ static void ma_decoding_backend_uninit__libopus(
600
+ void *pUserData,
601
+ ma_data_source *pBackend,
602
+ const ma_allocation_callbacks *pAllocationCallbacks) {
603
+ ma_libopus *pOpus = (ma_libopus *)pBackend;
604
+
605
+ (void)pUserData;
606
+
607
+ ma_libopus_uninit(pOpus, pAllocationCallbacks);
608
+ ma_free(pOpus, pAllocationCallbacks);
609
+ }
610
+
611
+ static ma_decoding_backend_vtable ma_gDecodingBackendVTable_libopus = {
612
+ ma_decoding_backend_init__libopus,
613
+ ma_decoding_backend_init_file__libopus,
614
+ NULL, /* onInitFileW() */
615
+ NULL, /* onInitMemory() */
616
+ ma_decoding_backend_uninit__libopus};
617
+ ma_decoding_backend_vtable *ma_decoding_backend_libopus =
618
+ &ma_gDecodingBackendVTable_libopus;
619
+ #else
620
+ ma_decoding_backend_vtable *ma_decoding_backend_libopus = NULL;
621
+ #endif
622
+
623
+ #endif /* miniaudio_libopus_c */
@@ -0,0 +1,71 @@
1
+ /*
2
+ This implements a data source that decodes Opus streams via libopus +
3
+ libopusfile
4
+
5
+ This object can be plugged into any `ma_data_source_*()` API and can also be
6
+ used as a custom decoding backend. See the custom_decoder example.
7
+ */
8
+ #ifndef miniaudio_libopus_h
9
+ #define miniaudio_libopus_h
10
+
11
+ #ifdef __cplusplus
12
+ extern "C" {
13
+ #endif
14
+
15
+ #include <audioapi/libs/miniaudio/miniaudio.h>
16
+
17
+ typedef struct {
18
+ ma_data_source_base
19
+ ds; /* The libopus decoder can be used independently as a data source. */
20
+ ma_read_proc onRead;
21
+ ma_seek_proc onSeek;
22
+ ma_tell_proc onTell;
23
+ void *pReadSeekTellUserData;
24
+ ma_format format; /* Will be either f32 or s16. */
25
+ /*OggOpusFile**/ void *of; /* Typed as void* so we can avoid a dependency on
26
+ opusfile in the header section. */
27
+ } ma_libopus;
28
+
29
+ MA_API ma_result ma_libopus_init(
30
+ ma_read_proc onRead,
31
+ ma_seek_proc onSeek,
32
+ ma_tell_proc onTell,
33
+ void *pReadSeekTellUserData,
34
+ const ma_decoding_backend_config *pConfig,
35
+ const ma_allocation_callbacks *pAllocationCallbacks,
36
+ ma_libopus *pOpus);
37
+ MA_API ma_result ma_libopus_init_file(
38
+ const char *pFilePath,
39
+ const ma_decoding_backend_config *pConfig,
40
+ const ma_allocation_callbacks *pAllocationCallbacks,
41
+ ma_libopus *pOpus);
42
+ MA_API void ma_libopus_uninit(
43
+ ma_libopus *pOpus,
44
+ const ma_allocation_callbacks *pAllocationCallbacks);
45
+ MA_API ma_result ma_libopus_read_pcm_frames(
46
+ ma_libopus *pOpus,
47
+ void *pFramesOut,
48
+ ma_uint64 frameCount,
49
+ ma_uint64 *pFramesRead);
50
+ MA_API ma_result
51
+ ma_libopus_seek_to_pcm_frame(ma_libopus *pOpus, ma_uint64 frameIndex);
52
+ MA_API ma_result ma_libopus_get_data_format(
53
+ ma_libopus *pOpus,
54
+ ma_format *pFormat,
55
+ ma_uint32 *pChannels,
56
+ ma_uint32 *pSampleRate,
57
+ ma_channel *pChannelMap,
58
+ size_t channelMapCap);
59
+ MA_API ma_result
60
+ ma_libopus_get_cursor_in_pcm_frames(ma_libopus *pOpus, ma_uint64 *pCursor);
61
+ MA_API ma_result
62
+ ma_libopus_get_length_in_pcm_frames(ma_libopus *pOpus, ma_uint64 *pLength);
63
+
64
+ /* Decoding backend vtable. This is what you'll plug into
65
+ * ma_decoder_config.pBackendVTables. No user data required. */
66
+ extern ma_decoding_backend_vtable *ma_decoding_backend_libopus;
67
+
68
+ #ifdef __cplusplus
69
+ }
70
+ #endif
71
+ #endif /* miniaudio_libopus_h */