porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c
Go to the documentation of this file.
1 #define DR_WAV_IMPLEMENTATION
2 #include "../../dr_wav.h"
3 #include <sndfile.h>
4 #include "../common/dr_common.c"
5 
7 
8 typedef SNDFILE* (* pfn_sf_open_virtual)(SF_VIRTUAL_IO* sfvirtual, int mode, SF_INFO* sfinfo, void* user_data);
9 typedef int (* pfn_sf_close) (SNDFILE* sndfile);
10 typedef sf_count_t (* pfn_sf_readf_short) (SNDFILE *sndfile, short *ptr, sf_count_t frames);
11 typedef sf_count_t (* pfn_sf_readf_int) (SNDFILE *sndfile, int *ptr, sf_count_t frames);
12 typedef sf_count_t (* pfn_sf_readf_float) (SNDFILE *sndfile, float *ptr, sf_count_t frames);
13 typedef sf_count_t (* pfn_sf_readf_double)(SNDFILE *sndfile, double *ptr, sf_count_t frames);
14 typedef sf_count_t (* pfn_sf_seek) (SNDFILE *sndfile, sf_count_t frames, int whence);
15 
23 
25 {
26  unsigned int i;
27  const char* pFileNames[] = {
28 #if defined(_WIN32)
29  #if defined(_WIN64)
30  "libsndfile-1-x64.dll",
31  #else
32  "libsndfile-1-x86.dll",
33  #endif
34  "libsndfile-1.dll"
35 #else
36  "libsndfile-1.so",
37  "libsndfile.so.1"
38 #endif
39  };
40 
41  if (g_libsndfile != NULL) {
42  return DRWAV_INVALID_OPERATION; /* Already initialized. */
43  }
44 
45  for (i = 0; i < sizeof(pFileNames)/sizeof(pFileNames[0]); i += 1) {
46  g_libsndfile = dr_dlopen(pFileNames[i]);
47  if (g_libsndfile != NULL) {
48  break;
49  }
50  }
51 
52  if (g_libsndfile == NULL) {
53  return DRWAV_ERROR; /* Unable to load libsndfile-1.so/dll. */
54  }
55 
63 
64  return DRWAV_SUCCESS;
65 }
66 
68 {
69  if (g_libsndfile == NULL) {
70  return; /* Invalid operation. Not initialized. */
71  }
72 
75 }
76 
77 typedef struct
78 {
79  SNDFILE* pHandle;
80  SF_INFO info;
83  size_t fileReadPos;
84 } libsndfile;
85 
86 sf_count_t libsndfile__on_filelen(void *user_data)
87 {
88  libsndfile* pSndFile = (libsndfile*)user_data;
89  return (sf_count_t)pSndFile->fileSizeInBytes;
90 }
91 
92 sf_count_t libsndfile__on_seek(sf_count_t offset, int whence, void *user_data)
93 {
94  libsndfile* pSndFile = (libsndfile*)user_data;
95 
96  switch (whence)
97  {
98  case SF_SEEK_SET:
99  {
100  pSndFile->fileReadPos = (size_t)offset;
101  } break;
102  case SF_SEEK_CUR:
103  {
104  pSndFile->fileReadPos += (size_t)offset;
105  } break;
106  case SF_SEEK_END:
107  {
108  pSndFile->fileReadPos = pSndFile->fileSizeInBytes - (size_t)offset;
109  } break;
110  }
111 
112  return (sf_count_t)pSndFile->fileReadPos;
113 }
114 
115 sf_count_t libsndfile__on_read(void *ptr, sf_count_t count, void *user_data)
116 {
117  libsndfile* pSndFile = (libsndfile*)user_data;
118 
119  DRWAV_COPY_MEMORY(ptr, pSndFile->pFileData + pSndFile->fileReadPos, (size_t)count);
120  pSndFile->fileReadPos += (size_t)count;
121 
122  return count;
123 }
124 
125 sf_count_t libsndfile__on_write(const void *ptr, sf_count_t count, void *user_data)
126 {
127  /* We're not doing anything with writing. */
128  (void)ptr;
129  (void)count;
130  (void)user_data;
131  return 0;
132 }
133 
134 sf_count_t libsndfile__on_tell(void *user_data)
135 {
136  libsndfile* pSndFile = (libsndfile*)user_data;
137  return (sf_count_t)pSndFile->fileReadPos;
138 }
139 
140 drwav_result libsndfile_init_file(const char* pFilePath, libsndfile* pSndFile)
141 {
142  SF_VIRTUAL_IO callbacks;
143 
144  if (pFilePath == NULL || pSndFile == NULL) {
145  return DRWAV_INVALID_ARGS;
146  }
147 
148  DRWAV_ZERO_MEMORY(pSndFile, sizeof(*pSndFile));
149 
150  /* We use libsndfile's virtual IO technique because we want to load from memory to make speed benchmarking fairer. */
151  pSndFile->pFileData = (drwav_uint8*)dr_open_and_read_file(pFilePath, &pSndFile->fileSizeInBytes);
152  if (pSndFile->pFileData == NULL) {
153  return DRWAV_ERROR; /* Failed to open the file. */
154  }
155 
156  DRWAV_ZERO_MEMORY(&callbacks, sizeof(callbacks));
157  callbacks.get_filelen = libsndfile__on_filelen;
158  callbacks.seek = libsndfile__on_seek;
159  callbacks.read = libsndfile__on_read;
160  callbacks.write = libsndfile__on_write;
161  callbacks.tell = libsndfile__on_tell;
162 
163  pSndFile->pHandle = libsndfile__sf_open_virtual(&callbacks, SFM_READ, &pSndFile->info, pSndFile);
164  if (pSndFile->pHandle == NULL) {
165  free(pSndFile->pFileData);
166  return DRWAV_ERROR;
167  }
168 
169  return DRWAV_SUCCESS;
170 }
171 
173 {
174  if (pSndFile == NULL) {
175  return;
176  }
177 
178  libsndfile__sf_close(pSndFile->pHandle);
179  free(pSndFile->pFileData);
180 }
181 
183 {
184  if (pSndFile == NULL || pBufferOut == NULL) {
185  return 0;
186  }
187 
188  /* Unfortunately it looks like libsndfile does not return correct integral values when the source file is floating point. */
189  if ((pSndFile->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT) {
190  /* Read as float and convert. */
191  drwav_uint64 totalFramesRead = 0;
192  while (totalFramesRead < framesToRead) {
193  float temp[4096];
194  drwav_uint64 framesRemaining = framesToRead - totalFramesRead;
195  drwav_uint64 framesReadThisIteration;
196  drwav_uint64 framesToReadThisIteration = sizeof(temp)/sizeof(temp[0]) / pSndFile->info.channels;
197  if (framesToReadThisIteration > framesRemaining) {
198  framesToReadThisIteration = framesRemaining;
199  }
200 
201  framesReadThisIteration = libsndfile__sf_readf_float(pSndFile->pHandle, temp, (sf_count_t)framesToReadThisIteration);
202 
203  drwav_f32_to_s16(pBufferOut, temp, (size_t)(framesReadThisIteration*pSndFile->info.channels));
204 
205  totalFramesRead += framesReadThisIteration;
206  pBufferOut += framesReadThisIteration*pSndFile->info.channels;
207 
208  /* If we read less frames than we requested we've reached the end of the file. */
209  if (framesReadThisIteration < framesToReadThisIteration) {
210  break;
211  }
212  }
213 
214  return totalFramesRead;
215  } else if ((pSndFile->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_DOUBLE) {
216  /* Read as double and convert. */
217  drwav_uint64 totalFramesRead = 0;
218  while (totalFramesRead < framesToRead) {
219  double temp[4096];
220  drwav_uint64 framesRemaining = framesToRead - totalFramesRead;
221  drwav_uint64 framesReadThisIteration;
222  drwav_uint64 framesToReadThisIteration = sizeof(temp)/sizeof(temp[0]) / pSndFile->info.channels;
223  if (framesToReadThisIteration > framesRemaining) {
224  framesToReadThisIteration = framesRemaining;
225  }
226 
227  framesReadThisIteration = libsndfile__sf_readf_double(pSndFile->pHandle, temp, (sf_count_t)framesToReadThisIteration);
228 
229  drwav_f64_to_s16(pBufferOut, temp, (size_t)(framesReadThisIteration*pSndFile->info.channels));
230 
231  totalFramesRead += framesReadThisIteration;
232  pBufferOut += framesReadThisIteration*pSndFile->info.channels;
233 
234  /* If we read less frames than we requested we've reached the end of the file. */
235  if (framesReadThisIteration < framesToReadThisIteration) {
236  break;
237  }
238  }
239 
240  return totalFramesRead;
241  } else {
242  return libsndfile__sf_readf_short(pSndFile->pHandle, pBufferOut, framesToRead);
243  }
244 }
245 
246 drwav_uint64 libsndfile_read_pcm_frames_f32(libsndfile* pSndFile, drwav_uint64 framesToRead, float* pBufferOut)
247 {
248  if (pSndFile == NULL || pBufferOut == NULL) {
249  return 0;
250  }
251 
252  return libsndfile__sf_readf_float(pSndFile->pHandle, pBufferOut, framesToRead);
253 }
254 
256 {
257  if (pSndFile == NULL || pBufferOut == NULL) {
258  return 0;
259  }
260 
261  /* Unfortunately it looks like libsndfile does not return correct integral values when the source file is floating point. */
262  if ((pSndFile->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT) {
263  /* Read and float and convert. */
264  drwav_uint64 totalFramesRead = 0;
265  while (totalFramesRead < framesToRead) {
266  float temp[4096];
267  drwav_uint64 framesRemaining = framesToRead - totalFramesRead;
268  drwav_uint64 framesReadThisIteration;
269  drwav_uint64 framesToReadThisIteration = sizeof(temp)/sizeof(temp[0]) / pSndFile->info.channels;
270  if (framesToReadThisIteration > framesRemaining) {
271  framesToReadThisIteration = framesRemaining;
272  }
273 
274  framesReadThisIteration = libsndfile__sf_readf_float(pSndFile->pHandle, temp, (sf_count_t)framesToReadThisIteration);
275 
276  drwav_f32_to_s32(pBufferOut, temp, (size_t)(framesReadThisIteration*pSndFile->info.channels));
277 
278  totalFramesRead += framesReadThisIteration;
279  pBufferOut += framesReadThisIteration*pSndFile->info.channels;
280 
281  /* If we read less frames than we requested we've reached the end of the file. */
282  if (framesReadThisIteration < framesToReadThisIteration) {
283  break;
284  }
285  }
286 
287  return totalFramesRead;
288  } else if ((pSndFile->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_DOUBLE) {
289  /* Read and double and convert. */
290  drwav_uint64 totalFramesRead = 0;
291  while (totalFramesRead < framesToRead) {
292  double temp[4096];
293  drwav_uint64 framesRemaining = framesToRead - totalFramesRead;
294  drwav_uint64 framesReadThisIteration;
295  drwav_uint64 framesToReadThisIteration = sizeof(temp)/sizeof(temp[0]) / pSndFile->info.channels;
296  if (framesToReadThisIteration > framesRemaining) {
297  framesToReadThisIteration = framesRemaining;
298  }
299 
300  framesReadThisIteration = libsndfile__sf_readf_double(pSndFile->pHandle, temp, (sf_count_t)framesToReadThisIteration);
301 
302  drwav_f64_to_s32(pBufferOut, temp, (size_t)(framesReadThisIteration*pSndFile->info.channels));
303 
304  totalFramesRead += framesReadThisIteration;
305  pBufferOut += framesReadThisIteration*pSndFile->info.channels;
306 
307  /* If we read less frames than we requested we've reached the end of the file. */
308  if (framesReadThisIteration < framesToReadThisIteration) {
309  break;
310  }
311  }
312 
313  return totalFramesRead;
314  } else {
315  return libsndfile__sf_readf_int(pSndFile->pHandle, pBufferOut, framesToRead);
316  }
317 }
318 
320 {
321  if (pSndFile == NULL) {
322  return DRWAV_FALSE;
323  }
324 
325  return libsndfile__sf_seek(pSndFile->pHandle, (sf_count_t)targetPCMFrameIndex, SF_SEEK_SET) == (sf_count_t)targetPCMFrameIndex;
326 }
DRWAV_INVALID_OPERATION
#define DRWAV_INVALID_OPERATION
Definition: porcupine/demo/c/dr_libs/dr_wav.h:201
DRWAV_FALSE
#define DRWAV_FALSE
Definition: porcupine/demo/c/dr_libs/dr_wav.h:165
libsndfile__sf_open_virtual
pfn_sf_open_virtual libsndfile__sf_open_virtual
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:16
drwav_bool32
drwav_uint32 drwav_bool32
Definition: porcupine/demo/c/dr_libs/dr_wav.h:163
libsndfile_init_file
drwav_result libsndfile_init_file(const char *pFilePath, libsndfile *pSndFile)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:140
libsndfile_read_pcm_frames_s16
drwav_uint64 libsndfile_read_pcm_frames_s16(libsndfile *pSndFile, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:182
libsndfile::pFileData
drwav_uint8 * pFileData
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:81
libsndfile::info
SF_INFO info
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:80
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
libsndfile_read_pcm_frames_f32
drwav_uint64 libsndfile_read_pcm_frames_f32(libsndfile *pSndFile, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:246
libsndfile__sf_readf_int
pfn_sf_readf_int libsndfile__sf_readf_int
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:19
dr_handle
void * dr_handle
Definition: porcupine/demo/c/dr_libs/tests/common/dr_common.c:83
DRWAV_SUCCESS
#define DRWAV_SUCCESS
Definition: porcupine/demo/c/dr_libs/dr_wav.h:198
libsndfile__sf_seek
pfn_sf_seek libsndfile__sf_seek
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:22
libsndfile__on_seek
sf_count_t libsndfile__on_seek(sf_count_t offset, int whence, void *user_data)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:92
libsndfile__sf_readf_short
pfn_sf_readf_short libsndfile__sf_readf_short
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:18
libsndfile__on_filelen
sf_count_t libsndfile__on_filelen(void *user_data)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:86
pfn_sf_seek
sf_count_t(* pfn_sf_seek)(SNDFILE *sndfile, sf_count_t frames, int whence)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:14
drwav_result
drwav_int32 drwav_result
Definition: porcupine/demo/c/dr_libs/dr_wav.h:197
drwav_f32_to_s32
DRWAV_API void drwav_f32_to_s32(drwav_int32 *pOut, const float *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50688
drwav_uint64
unsigned long long drwav_uint64
Definition: porcupine/demo/c/dr_libs/dr_wav.h:152
DRWAV_COPY_MEMORY
#define DRWAV_COPY_MEMORY(dst, src, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46294
libsndfile__on_read
sf_count_t libsndfile__on_read(void *ptr, sf_count_t count, void *user_data)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:115
dr_open_and_read_file
void * dr_open_and_read_file(const char *filePath, size_t *pFileSizeOut)
Definition: porcupine/demo/c/dr_libs/tests/common/dr_common.c:675
pfn_sf_readf_double
sf_count_t(* pfn_sf_readf_double)(SNDFILE *sndfile, double *ptr, sf_count_t frames)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:13
libsndfile__sf_readf_double
pfn_sf_readf_double libsndfile__sf_readf_double
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:21
libsndfile_uninit_api
void libsndfile_uninit_api()
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:67
libsndfile_uninit
void libsndfile_uninit(libsndfile *pSndFile)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:172
libsndfile_init_api
drwav_result libsndfile_init_api()
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:24
libsndfile::fileReadPos
size_t fileReadPos
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:83
pfn_sf_close
int(* pfn_sf_close)(SNDFILE *sndfile)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:9
drwav_int32
signed int drwav_int32
Definition: porcupine/demo/c/dr_libs/dr_wav.h:138
DRWAV_ZERO_MEMORY
#define DRWAV_ZERO_MEMORY(p, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46297
g_libsndfile
dr_handle g_libsndfile
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:6
libsndfile__on_write
sf_count_t libsndfile__on_write(const void *ptr, sf_count_t count, void *user_data)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:125
pfn_sf_readf_short
sf_count_t(* pfn_sf_readf_short)(SNDFILE *sndfile, short *ptr, sf_count_t frames)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:10
drwav_f32_to_s16
DRWAV_API void drwav_f32_to_s16(drwav_int16 *pOut, const float *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50091
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
dr_dlsym
dr_proc dr_dlsym(dr_handle handle, const char *symbol)
Definition: porcupine/demo/c/dr_libs/tests/common/dr_common.c:939
libsndfile::pHandle
SNDFILE * pHandle
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:79
dr_dlclose
void dr_dlclose(dr_handle handle)
Definition: porcupine/demo/c/dr_libs/tests/common/dr_common.c:930
drwav_int16
signed short drwav_int16
Definition: porcupine/demo/c/dr_libs/dr_wav.h:136
drwav_uint8
unsigned char drwav_uint8
Definition: porcupine/demo/c/dr_libs/dr_wav.h:135
pfn_sf_open_virtual
SNDFILE *(* pfn_sf_open_virtual)(SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:8
dr_dlopen
dr_handle dr_dlopen(const char *filename)
Definition: porcupine/demo/c/dr_libs/tests/common/dr_common.c:917
libsndfile_read_pcm_frames_s32
drwav_uint64 libsndfile_read_pcm_frames_s32(libsndfile *pSndFile, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:255
libsndfile::fileSizeInBytes
size_t fileSizeInBytes
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:82
pfn_sf_readf_float
sf_count_t(* pfn_sf_readf_float)(SNDFILE *sndfile, float *ptr, sf_count_t frames)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:12
libsndfile__sf_close
pfn_sf_close libsndfile__sf_close
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:17
libsndfile__sf_readf_float
pfn_sf_readf_float libsndfile__sf_readf_float
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:20
drwav_f64_to_s32
DRWAV_API void drwav_f64_to_s32(drwav_int32 *pOut, const double *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50698
DRWAV_INVALID_ARGS
#define DRWAV_INVALID_ARGS
Definition: porcupine/demo/c/dr_libs/dr_wav.h:200
DRWAV_ERROR
#define DRWAV_ERROR
Definition: porcupine/demo/c/dr_libs/dr_wav.h:199
libsndfile
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:77
drwav_f64_to_s16
DRWAV_API void drwav_f64_to_s16(drwav_int16 *pOut, const double *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50105
libsndfile__on_tell
sf_count_t libsndfile__on_tell(void *user_data)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:134
pfn_sf_readf_int
sf_count_t(* pfn_sf_readf_int)(SNDFILE *sndfile, int *ptr, sf_count_t frames)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:11
libsndfile_seek_to_pcm_frame
drwav_bool32 libsndfile_seek_to_pcm_frame(libsndfile *pSndFile, drwav_uint64 targetPCMFrameIndex)
Definition: porcupine/demo/c/dr_libs/tests/wav/dr_wav_common.c:319


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