pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c
Go to the documentation of this file.
1 /*
2 USAGE: audioconverter [input file] [output file] [format] [channels] [rate]
3 
4 EXAMPLES:
5  audioconverter my_file.flac my_file.wav
6  audioconverter my_file.flac my_file.wav f32 44100 linear --linear-order 8
7  audioconverter my_file.flac my_file.wav s16 2 44100 speex --speex-quality 10
8 */
9 
10 /*
11 Note about Speex resampling. If you decide to enable the Speex resampler with ENABLE_SPEEX, this program will use licensed third party code. If you compile and
12 redistribute this program you need to include a copy of the license which can be found at https://github.com/xiph/opus-tools/blob/master/COPYING. You can also
13 find a copy of this text in extras/speex_resampler/README.md in the miniaudio repository.
14 */
15 #define _CRT_SECURE_NO_WARNINGS /* For stb_vorbis' usage of fopen() instead of fopen_s(). */
16 
17 #define STB_VORBIS_HEADER_ONLY
18 #include "../../extras/stb_vorbis.c" /* Enables Vorbis decoding. */
19 
20 /* Enable Speex resampling, but only if requested on the command line at build time. */
21 #if defined(ENABLE_SPEEX)
22  #define MINIAUDIO_SPEEX_RESAMPLER_IMPLEMENTATION
23  #include "../../extras/speex_resampler/ma_speex_resampler.h"
24 #endif
25 
26 #define MA_NO_DEVICE_IO
27 #define MA_NO_THREADING
28 #define MINIAUDIO_IMPLEMENTATION
29 #include "../../miniaudio.h"
30 
31 #include <stdio.h>
32 
34 {
35  printf("USAGE: audioconverter [input file] [output file] [format] [channels] [rate]\n");
36  printf(" [format] is optional and can be one of the following:\n");
37  printf(" u8 8-bit unsigned integer\n");
38  printf(" s16 16-bit signed integer\n");
39  printf(" s24 24-bit signed integer (tightly packed)\n");
40  printf(" s32 32-bit signed integer\n");
41  printf(" f32 32-bit floating point\n");
42  printf(" [channels] is optional and in the range of %d and %d\n", MA_MIN_CHANNELS, MA_MAX_CHANNELS);
43  printf(" [rate] is optional and in the range of %d and %d\n", MA_MIN_SAMPLE_RATE, MA_MAX_SAMPLE_RATE);
44  printf("\n");
45  printf("PARAMETERS:\n");
46  printf(" --linear-order [0..%d]\n", MA_MAX_FILTER_ORDER);
47  printf(" --speex-quality [0..10]\n");
48 }
49 
51 {
52  ma_result result = MA_SUCCESS;
53 
54  MA_ASSERT(pDecoder != NULL);
55  MA_ASSERT(pEncoder != NULL);
56 
57  /*
58  All we do is read from the decoder and then write straight to the encoder. All of the neccessary data conversion
59  will happen internally.
60  */
61  for (;;) {
63  ma_uint64 framesReadThisIteration;
64  ma_uint64 framesToReadThisIteration;
65 
66  framesToReadThisIteration = sizeof(pRawData) / ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels);
67  framesReadThisIteration = ma_decoder_read_pcm_frames(pDecoder, pRawData, framesToReadThisIteration);
68  if (framesReadThisIteration == 0) {
69  break; /* Reached the end. */
70  }
71 
72  /* At this point we have the raw data from the decoder. We now just need to write it to the encoder. */
73  ma_encoder_write_pcm_frames(pEncoder, pRawData, framesReadThisIteration);
74 
75  /* Get out of the loop if we've reached the end. */
76  if (framesReadThisIteration < framesToReadThisIteration) {
77  break;
78  }
79  }
80 
81  return result;
82 }
83 
84 ma_bool32 is_number(const char* str)
85 {
86  if (str == NULL || str[0] == '\0') {
87  return MA_FALSE;
88  }
89 
90  while (str[0] != '\0') {
91  if (str[0] < '0' || str[0] > '9') {
92  return MA_FALSE;
93  }
94 
95  str += 1;
96  }
97 
98  return MA_TRUE;
99 }
100 
102 {
103  ma_uint32 x;
104 
105  if (!is_number(str)) {
106  return MA_FALSE; /* Not an integer. */
107  }
108 
109  x = (ma_uint32)atoi(str);
110  if (x < lo || x > hi) {
111  return MA_FALSE; /* Out of range. */
112  }
113 
114  if (pValue != NULL) {
115  *pValue = x;
116  }
117 
118  return MA_TRUE;
119 }
120 
121 ma_bool32 try_parse_format(const char* str, ma_format* pValue)
122 {
123  ma_format format;
124 
125  /* */ if (strcmp(str, "u8") == 0) {
126  format = ma_format_u8;
127  } else if (strcmp(str, "s16") == 0) {
128  format = ma_format_s16;
129  } else if (strcmp(str, "s24") == 0) {
130  format = ma_format_s24;
131  } else if (strcmp(str, "s32") == 0) {
132  format = ma_format_s32;
133  } else if (strcmp(str, "f32") == 0) {
134  format = ma_format_f32;
135  } else {
136  return MA_FALSE; /* Not a format. */
137  }
138 
139  if (pValue != NULL) {
140  *pValue = format;
141  }
142 
143  return MA_TRUE;;
144 }
145 
146 ma_bool32 try_parse_channels(const char* str, ma_uint32* pValue)
147 {
149 }
150 
151 ma_bool32 try_parse_sample_rate(const char* str, ma_uint32* pValue)
152 {
154 }
155 
157 {
158  ma_resample_algorithm algorithm;
159 
160  /* */ if (strcmp(str, "linear") == 0) {
161  algorithm = ma_resample_algorithm_linear;
162  } else if (strcmp(str, "speex") == 0) {
163  algorithm = ma_resample_algorithm_speex;
164  } else {
165  return MA_FALSE; /* Not a valid algorithm */
166  }
167 
168  if (pValue != NULL) {
169  *pValue = algorithm;
170  }
171 
172  return MA_TRUE;
173 }
174 
175 int main(int argc, char** argv)
176 {
177  ma_result result;
178  ma_decoder_config decoderConfig;
180  ma_encoder_config encoderConfig;
182  ma_resource_format outputResourceFormat;
183  ma_format format = ma_format_unknown;
184  ma_uint32 channels = 0;
185  ma_uint32 rate = 0;
186  ma_resample_algorithm resampleAlgorithm;
187  ma_uint32 linearOrder = 8;
188  ma_uint32 speexQuality = 3;
189  int iarg;
190  const char* pOutputFilePath;
191 
192  print_usage();
193 
194  /* Print help if requested. */
195  if (argc == 2) {
196  if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
197  print_usage();
198  return 0;
199  }
200  }
201 
202  if (argc < 3) {
203  print_usage();
204  return -1;
205  }
206 
207  /* Default to Speex if it's enabled. */
208 #if defined(ENABLE_SPEEX)
209  resampleAlgorithm = ma_resample_algorithm_speex;
210 #else
211  resampleAlgorithm = ma_resample_algorithm_linear;
212 #endif
213 
214  /*
215  The fourth and fifth arguments can be a format and/or rate specifier. It doesn't matter which order they are in as we can identify them by whether or
216  not it's a number. If it's a number we assume it's a sample rate, otherwise we assume it's a format specifier.
217  */
218  for (iarg = 3; iarg < argc; iarg += 1) {
219  if (strcmp(argv[iarg], "--linear-order") == 0) {
220  iarg += 1;
221  if (iarg >= argc) {
222  break;
223  }
224 
225  if (!try_parse_uint32_in_range(argv[iarg], &linearOrder, 0, 8)) {
226  printf("Expecting a number between 0 and %d for --linear-order.\n", MA_MAX_FILTER_ORDER);
227  return -1;
228  }
229 
230  continue;
231  }
232 
233  if (strcmp(argv[iarg], "--speex-quality") == 0) {
234  iarg += 1;
235  if (iarg >= argc) {
236  break;
237  }
238 
239  if (!try_parse_uint32_in_range(argv[iarg], &speexQuality, 0, 10)) {
240  printf("Expecting a number between 0 and 10 for --speex-quality.\n");
241  return -1;
242  }
243 
244  continue;
245  }
246 
247  if (try_parse_resample_algorithm(argv[iarg], &resampleAlgorithm)) {
248  continue;
249  }
250 
251  if (try_parse_format(argv[iarg], &format)) {
252  continue;
253  }
254 
255  if (try_parse_channels(argv[iarg], &channels)) {
256  continue;
257  }
258 
259  if (try_parse_sample_rate(argv[iarg], &rate)) {
260  continue;
261  }
262 
263  /* Getting here means we have an unknown parameter. */
264  printf("Warning: Unknown parameter \"%s\"", argv[iarg]);
265  }
266 
267  /* Initialize a decoder for the input file. */
268  decoderConfig = ma_decoder_config_init(format, channels, rate);
269  decoderConfig.resampling.algorithm = resampleAlgorithm;
270  decoderConfig.resampling.linear.lpfOrder = linearOrder;
271 #if defined(ENABLE_SPEEX)
272  decoderConfig.resampling.speex.quality = speexQuality;
273 #endif
274 
275  result = ma_decoder_init_file(argv[1], &decoderConfig, &decoder);
276  if (result != MA_SUCCESS) {
277  printf("Failed to open input file. Check the file exists and the format is supported. Supported input formats:\n");
278  #if defined(dr_opus_h)
279  printf(" Opus\n");
280  #endif
281  #if defined(dr_mp3_h)
282  printf(" MP3\n");
283  #endif
284  #if defined(dr_flac_h)
285  printf(" FLAC\n");
286  #endif
287  #if defined(STB_VORBIS_INCLUDE_STB_VORBIS_H)
288  printf(" Vorbis\n");
289  #endif
290  #if defined(dr_wav_h)
291  printf(" WAV\n");
292  #endif
293  return (int)result;
294  }
295 
296 
297  pOutputFilePath = argv[2];
298 
299  outputResourceFormat = ma_resource_format_wav; /* Wave by default in case we don't know the file extension. */
300  if (ma_path_extension_equal(pOutputFilePath, "wav")) {
301  outputResourceFormat = ma_resource_format_wav;
302  } else {
303  printf("Warning: Unknown file extension \"%s\". Encoding as WAV.\n", ma_path_extension(pOutputFilePath));
304  }
305 
306  /* Initialize the encoder for the output file. */
308  result = ma_encoder_init_file(pOutputFilePath, &encoderConfig, &encoder);
309  if (result != MA_SUCCESS) {
311  printf("Failed to open output file. Check that the directory exists and that the file is not already opened by another process. %s", ma_result_description(result));
312  return -1;
313  }
314 
315 
316  /* We have our decoder and encoder ready, so now we can do the conversion. */
317  result = do_conversion(&decoder, &encoder);
318 
319 
320  /* Done. */
323 
324  return (int)result;
325 }
326 
327 
328 /* stb_vorbis implementation must come after the implementation of miniaudio. */
329 #if defined(_MSC_VER) && !defined(__clang__)
330  #pragma warning(push)
331  #pragma warning(disable:4100) /* unreferenced formal parameter */
332  #pragma warning(disable:4244) /* '=': conversion from '' to '', possible loss of data */
333  #pragma warning(disable:4245) /* '=': conversion from '' to '', signed/unsigned mismatch */
334  #pragma warning(disable:4456) /* declaration of '' hides previous local declaration */
335  #pragma warning(disable:4457) /* declaration of '' hides function parameter */
336  #pragma warning(disable:4701) /* potentially uninitialized local variable '' used */
337 #else
338 #endif
339 #undef STB_VORBIS_HEADER_ONLY
340 #include "../../extras/stb_vorbis.c"
341 #if defined(_MSC_VER) && !defined(__clang__)
342  #pragma warning(pop)
343 #else
344 #endif
ma_uint64
uint64_t ma_uint64
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1505
ma_get_bytes_per_frame
static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels)
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2673
MA_FALSE
#define MA_FALSE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1531
do_conversion
ma_result do_conversion(ma_decoder *pDecoder, ma_encoder *pEncoder)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:50
try_parse_sample_rate
ma_bool32 try_parse_sample_rate(const char *str, ma_uint32 *pValue)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:151
ma_uint8
uint8_t ma_uint8
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1499
ma_encoder_config
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5313
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
ma_resource_format_wav
@ ma_resource_format_wav
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5147
ma_decoder_uninit
ma_result ma_decoder_uninit(ma_decoder *pDecoder)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44739
ma_decoder_config
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5170
ma_resample_algorithm
ma_resample_algorithm
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2234
ma_bool32
ma_uint32 ma_bool32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1529
ma_format_f32
@ ma_format_f32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1790
ma_decoder_config::resampling
struct ma_decoder_config::@122 resampling
MA_DATA_CONVERTER_STACK_BUFFER_SIZE
#define MA_DATA_CONVERTER_STACK_BUFFER_SIZE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4226
ma_decoder_config::linear
struct ma_decoder_config::@122::@123 linear
ma_decoder_config_init
ma_decoder_config ma_decoder_config_init(ma_format outputFormat, ma_uint32 outputChannels, ma_uint32 outputSampleRate)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:40646
ma_format_s32
@ ma_format_s32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1789
decoder
ma_decoder decoder
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:61
ma_format
ma_format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1779
try_parse_format
ma_bool32 try_parse_format(const char *str, ma_format *pValue)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:121
ma_format_s24
@ ma_format_s24
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1788
ma_decoder_config::speex
struct ma_decoder_config::@122::@124 speex
ma_decoder::outputFormat
ma_format outputFormat
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5203
ma_format_unknown
@ ma_format_unknown
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1785
ma_encoder_write_pcm_frames
ma_uint64 ma_encoder_write_pcm_frames(ma_encoder *pEncoder, const void *pFramesIn, ma_uint64 frameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45351
try_parse_resample_algorithm
ma_bool32 try_parse_resample_algorithm(const char *str, ma_resample_algorithm *pValue)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:156
encoder
ma_encoder encoder
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:62
ma_result_description
const char * ma_result_description(ma_result result)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:37039
try_parse_channels
ma_bool32 try_parse_channels(const char *str, ma_uint32 *pValue)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:146
ma_path_extension
static const char * ma_path_extension(const char *path)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44130
ma_result
int ma_result
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1658
ma_encoder_uninit
void ma_encoder_uninit(ma_encoder *pEncoder)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45334
ma_encoder
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5324
ma_format_s16
@ ma_format_s16
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1787
ma_encoder_init_file
ma_result ma_encoder_init_file(const char *pFilePath, const ma_encoder_config *pConfig, ma_encoder *pEncoder)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45279
ma_encoder_config_init
ma_encoder_config ma_encoder_config_init(ma_resource_format resourceFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45183
try_parse_uint32_in_range
ma_bool32 try_parse_uint32_in_range(const char *str, ma_uint32 *pValue, ma_uint32 lo, ma_uint32 hi)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:101
ma_decoder
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5193
MA_ASSERT
#define MA_ASSERT(condition)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:770
MA_MAX_SAMPLE_RATE
#define MA_MAX_SAMPLE_RATE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1755
main
int main(int argc, char **argv)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:175
ma_uint32
uint32_t ma_uint32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1503
ma_format_u8
@ ma_format_u8
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1786
ma_decoder_read_pcm_frames
ma_uint64 ma_decoder_read_pcm_frames(ma_decoder *pDecoder, void *pFramesOut, ma_uint64 frameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44808
ma_decoder_config::algorithm
ma_resample_algorithm algorithm
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5180
ma_resample_algorithm_linear
@ ma_resample_algorithm_linear
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2236
ma_resource_format
ma_resource_format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5145
ma_decoder::outputChannels
ma_uint32 outputChannels
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5204
MA_MIN_CHANNELS
#define MA_MIN_CHANNELS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1752
ma_decoder_init_file
ma_result ma_decoder_init_file(const char *pFilePath, const ma_decoder_config *pConfig, ma_decoder *pDecoder)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44687
python.test_porcupine.argv
argv
Definition: test_porcupine.py:158
MA_MAX_CHANNELS
#define MA_MAX_CHANNELS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1753
ma_resample_algorithm_speex
@ ma_resample_algorithm_speex
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2237
MA_TRUE
#define MA_TRUE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1530
MA_SUCCESS
#define MA_SUCCESS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1659
ma_path_extension_equal
static ma_bool32 ma_path_extension_equal(const char *path, const char *extension)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44181
MA_MIN_SAMPLE_RATE
#define MA_MIN_SAMPLE_RATE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1754
print_usage
void print_usage()
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:33
is_number
ma_bool32 is_number(const char *str)
Definition: pvrecorder/src/miniaudio/tools/audioconverter/audioconverter.c:84
ma_decoder::outputSampleRate
ma_uint32 outputSampleRate
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5205
MA_MAX_FILTER_ORDER
#define MA_MAX_FILTER_ORDER
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1758


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:47