7
7
#define MINIAUDIO_IMPLEMENTATION
8
8
#include < audioapi/libs/miniaudio/miniaudio.h>
9
9
10
+ #include < audioapi/libs/miniaudio/decoders/libopus/miniaudio_libopus.h>
11
+ #include < audioapi/libs/miniaudio/decoders/libvorbis/miniaudio_libvorbis.h>
12
+
10
13
// #include <android/log.h>
11
14
12
15
namespace audioapi {
13
16
17
+ // Decoding audio in fixed-size chunks because total frame count can't be
18
+ // determined in advance. Note: ma_decoder_get_length_in_pcm_frames() always
19
+ // returns 0 for Vorbis decoders.
20
+ std::vector<int16_t > AudioDecoder::readAllPcmFrames (
21
+ ma_decoder &decoder,
22
+ int numChannels,
23
+ ma_uint64 &outFramesRead) const {
24
+ std::vector<int16_t > buffer;
25
+ int16_t temp[CHUNK_SIZE * numChannels];
26
+ outFramesRead = 0 ;
27
+
28
+ while (true ) {
29
+ ma_uint64 tempFramesDecoded = 0 ;
30
+ ma_decoder_read_pcm_frames (&decoder, temp, CHUNK_SIZE, &tempFramesDecoded);
31
+ if (tempFramesDecoded == 0 ) {
32
+ break ;
33
+ }
34
+
35
+ buffer.insert (buffer.end (), temp, temp + tempFramesDecoded * numChannels);
36
+ outFramesRead += tempFramesDecoded;
37
+ }
38
+
39
+ return buffer;
40
+ }
41
+
42
+ std::shared_ptr<AudioBus> AudioDecoder::makeAudioBusFromInt16Buffer (
43
+ const std::vector<int16_t > &buffer,
44
+ int numChannels,
45
+ float sampleRate) const {
46
+ auto outputFrames = buffer.size () / numChannels;
47
+ auto audioBus =
48
+ std::make_shared<AudioBus>(outputFrames, numChannels, sampleRate);
49
+
50
+ for (int ch = 0 ; ch < numChannels; ++ch) {
51
+ auto channelData = audioBus->getChannel (ch)->getData ();
52
+ for (int i = 0 ; i < outputFrames; ++i) {
53
+ channelData[i] = int16ToFloat (buffer[i * numChannels + ch]);
54
+ }
55
+ }
56
+ return audioBus;
57
+ }
58
+
14
59
std::shared_ptr<AudioBus> AudioDecoder::decodeWithFilePath (
15
60
const std::string &path) const {
16
61
ma_decoder decoder;
17
62
ma_decoder_config config = ma_decoder_config_init (
18
63
ma_format_s16, numChannels_, static_cast <int >(sampleRate_));
19
- ma_result result = ma_decoder_init_file (path.c_str (), &config, &decoder);
20
- if (result != MA_SUCCESS) {
64
+ #ifndef AUDIO_API_TEST_SUITE
65
+ ma_decoding_backend_vtable *customBackends[] = {
66
+ ma_decoding_backend_libvorbis, ma_decoding_backend_libopus};
67
+
68
+ config.ppCustomBackendVTables = customBackends;
69
+ config.customBackendCount =
70
+ sizeof (customBackends) / sizeof (customBackends[0 ]);
71
+ #endif
72
+
73
+ if (ma_decoder_init_file (path.c_str (), &config, &decoder) != MA_SUCCESS) {
21
74
// __android_log_print(
22
- // ANDROID_LOG_ERROR,
23
- // "AudioDecoder",
24
- // "Failed to initialize decoder for file: %s",
25
- // path.c_str());
75
+ // ANDROID_LOG_ERROR,
76
+ // "AudioDecoder",
77
+ // "Failed to initialize decoder for file: %s",
78
+ // path.c_str());
26
79
ma_decoder_uninit (&decoder);
27
-
28
80
return nullptr ;
29
81
}
30
82
31
- ma_uint64 totalFrameCount;
32
- ma_decoder_get_length_in_pcm_frames (&decoder, &totalFrameCount);
33
-
34
- std::vector<int16_t > buffer (totalFrameCount * numChannels_);
35
-
36
- ma_uint64 framesDecoded;
37
- ma_decoder_read_pcm_frames (
38
- &decoder, buffer.data (), totalFrameCount, &framesDecoded);
39
-
40
- if (framesDecoded == 0 ) {
83
+ ma_uint64 framesRead = 0 ;
84
+ auto buffer = readAllPcmFrames (decoder, numChannels_, framesRead);
85
+ if (framesRead == 0 ) {
41
86
// __android_log_print(ANDROID_LOG_ERROR, "AudioDecoder", "Failed to
42
87
// decode");
43
-
44
88
ma_decoder_uninit (&decoder);
45
89
return nullptr ;
46
90
}
47
91
48
- auto outputFrames = buffer.size () / numChannels_;
49
- auto audioBus =
50
- std::make_shared<AudioBus>(outputFrames, numChannels_, sampleRate_);
51
-
52
- for (int i = 0 ; i < numChannels_; ++i) {
53
- auto channelData = audioBus->getChannel (i)->getData ();
54
-
55
- for (ma_uint64 j = 0 ; j < outputFrames; ++j) {
56
- channelData[j] = int16ToFloat (buffer[j * numChannels_ + i]);
57
- }
58
- }
59
-
60
92
ma_decoder_uninit (&decoder);
61
-
62
- return audioBus;
93
+ return makeAudioBusFromInt16Buffer (buffer, numChannels_, sampleRate_);
63
94
}
64
95
65
96
std::shared_ptr<AudioBus> AudioDecoder::decodeWithMemoryBlock (
@@ -68,49 +99,36 @@ std::shared_ptr<AudioBus> AudioDecoder::decodeWithMemoryBlock(
68
99
ma_decoder decoder;
69
100
ma_decoder_config config = ma_decoder_config_init (
70
101
ma_format_s16, numChannels_, static_cast <int >(sampleRate_));
71
- ma_result result = ma_decoder_init_memory (data, size, &config, &decoder);
72
- if (result != MA_SUCCESS) {
102
+
103
+ #ifndef AUDIO_API_TEST_SUITE
104
+ ma_decoding_backend_vtable *customBackends[] = {
105
+ ma_decoding_backend_libvorbis, ma_decoding_backend_libopus};
106
+
107
+ config.ppCustomBackendVTables = customBackends;
108
+ config.customBackendCount =
109
+ sizeof (customBackends) / sizeof (customBackends[0 ]);
110
+ #endif
111
+
112
+ if (ma_decoder_init_memory (data, size, &config, &decoder) != MA_SUCCESS) {
73
113
// __android_log_print(
74
- // ANDROID_LOG_ERROR,
75
- // "AudioDecoder",
76
- // "Failed to initialize decoder for memory block");
114
+ // ANDROID_LOG_ERROR,
115
+ // "AudioDecoder",
116
+ // "Failed to initialize decoder for memory block");
77
117
ma_decoder_uninit (&decoder);
78
-
79
118
return nullptr ;
80
119
}
81
120
82
- ma_uint64 totalFrameCount;
83
- ma_decoder_get_length_in_pcm_frames (&decoder, &totalFrameCount);
84
-
85
- std::vector<int16_t > buffer (totalFrameCount * numChannels_);
86
-
87
- ma_uint64 framesDecoded;
88
- ma_decoder_read_pcm_frames (
89
- &decoder, buffer.data (), totalFrameCount, &framesDecoded);
90
-
91
- if (framesDecoded == 0 ) {
121
+ ma_uint64 framesRead = 0 ;
122
+ auto buffer = readAllPcmFrames (decoder, numChannels_, framesRead);
123
+ if (framesRead == 0 ) {
92
124
// __android_log_print(ANDROID_LOG_ERROR, "AudioDecoder", "Failed to
93
125
// decode");
94
-
95
126
ma_decoder_uninit (&decoder);
96
127
return nullptr ;
97
128
}
98
129
99
- auto outputFrames = buffer.size () / numChannels_;
100
- auto audioBus =
101
- std::make_shared<AudioBus>(outputFrames, numChannels_, sampleRate_);
102
-
103
- for (int i = 0 ; i < numChannels_; ++i) {
104
- auto channelData = audioBus->getChannel (i)->getData ();
105
-
106
- for (ma_uint64 j = 0 ; j < outputFrames; ++j) {
107
- channelData[j] = int16ToFloat (buffer[j * numChannels_ + i]);
108
- }
109
- }
110
-
111
130
ma_decoder_uninit (&decoder);
112
-
113
- return audioBus;
131
+ return makeAudioBusFromInt16Buffer (buffer, numChannels_, sampleRate_);
114
132
}
115
133
116
134
std::shared_ptr<AudioBus> AudioDecoder::decodeWithPCMInBase64 (
0 commit comments