tinysndfile.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "tinysndfile"
  17. #include "audio/android/tinysndfile.h"
  18. #include "audio/android/audio_utils/include/audio_utils/primitives.h"
  19. #include "audio/android/cutils/log.h"
  20. // #ifdef HAVE_STDERR
  21. // #include <stdio.h>
  22. // #endif
  23. #include <string.h>
  24. #include <errno.h>
  25. #ifndef HAVE_STDERR
  26. #define HAVE_STDERR
  27. #endif
  28. #define WAVE_FORMAT_PCM 1
  29. #define WAVE_FORMAT_IEEE_FLOAT 3
  30. #define WAVE_FORMAT_EXTENSIBLE 0xFFFE
  31. static snd_callbacks __defaultCallback;
  32. static int __inited = 0;
  33. struct SNDFILE_ {
  34. uint8_t *temp; // realloc buffer used for shrinking 16 bits to 8 bits and byte-swapping
  35. void *stream;
  36. size_t bytesPerFrame;
  37. size_t remaining; // frames unread for SFM_READ, frames written for SFM_WRITE
  38. SF_INFO info;
  39. snd_callbacks callback;
  40. };
  41. static unsigned little2u(unsigned char *ptr)
  42. {
  43. return (ptr[1] << 8) + ptr[0];
  44. }
  45. static unsigned little4u(unsigned char *ptr)
  46. {
  47. return (ptr[3] << 24) + (ptr[2] << 16) + (ptr[1] << 8) + ptr[0];
  48. }
  49. static int isLittleEndian(void)
  50. {
  51. static const short one = 1;
  52. return *((const char *) &one) == 1;
  53. }
  54. // "swab" conflicts with OS X <string.h>
  55. static void my_swab(short *ptr, size_t numToSwap)
  56. {
  57. while (numToSwap > 0) {
  58. *ptr = little2u((unsigned char *) ptr);
  59. --numToSwap;
  60. ++ptr;
  61. }
  62. }
  63. static void* open_func(const char* path, void* user)
  64. {
  65. return fopen(path, "rb");
  66. }
  67. static size_t read_func(void *ptr, size_t size, size_t nmemb, void* datasource)
  68. {
  69. return fread(ptr, size, nmemb, (FILE*)datasource);
  70. }
  71. static int seek_func(void* datasource, long offset, int whence)
  72. {
  73. return fseek((FILE*)datasource, offset, whence);
  74. }
  75. static int close_func(void* datasource)
  76. {
  77. return fclose((FILE*)datasource);
  78. }
  79. static long tell_func(void* datasource)
  80. {
  81. return ftell((FILE*)datasource);
  82. }
  83. static void lazyInit()
  84. {
  85. if (__inited == 0)
  86. {
  87. __defaultCallback.open = open_func;
  88. __defaultCallback.read = read_func;
  89. __defaultCallback.seek = seek_func;
  90. __defaultCallback.close = close_func;
  91. __defaultCallback.tell = tell_func;
  92. __inited = 1;
  93. }
  94. }
  95. SNDFILE *sf_open_read(const char *path, SF_INFO *info, snd_callbacks* cb, void* user)
  96. {
  97. lazyInit();
  98. if (path == NULL || info == NULL) {
  99. #ifdef HAVE_STDERR
  100. ALOGE("path=%p info=%p\n", path, info);
  101. #endif
  102. return NULL;
  103. }
  104. SNDFILE *handle = (SNDFILE *) malloc(sizeof(SNDFILE));
  105. handle->temp = NULL;
  106. handle->info.format = SF_FORMAT_WAV;
  107. if (cb != NULL) {
  108. handle->callback = *cb;
  109. } else {
  110. handle->callback = __defaultCallback;
  111. }
  112. void* stream = handle->callback.open(path, user);
  113. if (stream == NULL) {
  114. #ifdef HAVE_STDERR
  115. ALOGE("fopen %s failed errno %d\n", path, errno);
  116. #endif
  117. free(handle);
  118. return NULL;
  119. }
  120. handle->stream = stream;
  121. // don't attempt to parse all valid forms, just the most common ones
  122. unsigned char wav[12];
  123. size_t actual;
  124. unsigned riffSize;
  125. size_t remaining;
  126. int hadFmt = 0;
  127. int hadData = 0;
  128. long dataTell = 0L;
  129. actual = handle->callback.read(wav, sizeof(char), sizeof(wav), stream);
  130. if (actual < 12) {
  131. #ifdef HAVE_STDERR
  132. ALOGE("actual %zu < 44\n", actual);
  133. #endif
  134. goto close;
  135. }
  136. if (memcmp(wav, "RIFF", 4)) {
  137. #ifdef HAVE_STDERR
  138. ALOGE("wav != RIFF\n");
  139. #endif
  140. goto close;
  141. }
  142. riffSize = little4u(&wav[4]);
  143. if (riffSize < 4) {
  144. #ifdef HAVE_STDERR
  145. ALOGE("riffSize %u < 4\n", riffSize);
  146. #endif
  147. goto close;
  148. }
  149. if (memcmp(&wav[8], "WAVE", 4)) {
  150. #ifdef HAVE_STDERR
  151. ALOGE("missing WAVE\n");
  152. #endif
  153. goto close;
  154. }
  155. remaining = riffSize - 4;
  156. while (remaining >= 8) {
  157. unsigned char chunk[8];
  158. actual = handle->callback.read(chunk, sizeof(char), sizeof(chunk), stream);
  159. if (actual != sizeof(chunk)) {
  160. #ifdef HAVE_STDERR
  161. ALOGE("actual %zu != %zu\n", actual, sizeof(chunk));
  162. #endif
  163. goto close;
  164. }
  165. remaining -= 8;
  166. unsigned chunkSize = little4u(&chunk[4]);
  167. if (chunkSize > remaining) {
  168. #ifdef HAVE_STDERR
  169. ALOGE("chunkSize %u > remaining %zu\n", chunkSize, remaining);
  170. #endif
  171. goto close;
  172. }
  173. if (!memcmp(&chunk[0], "fmt ", 4)) {
  174. if (hadFmt) {
  175. #ifdef HAVE_STDERR
  176. ALOGE("multiple fmt\n");
  177. #endif
  178. goto close;
  179. }
  180. if (chunkSize < 2) {
  181. #ifdef HAVE_STDERR
  182. ALOGE("chunkSize %u < 2\n", chunkSize);
  183. #endif
  184. goto close;
  185. }
  186. unsigned char fmt[40];
  187. actual = handle->callback.read(fmt, sizeof(char), 2, stream);
  188. if (actual != 2) {
  189. #ifdef HAVE_STDERR
  190. ALOGE("actual %zu != 2\n", actual);
  191. #endif
  192. goto close;
  193. }
  194. unsigned format = little2u(&fmt[0]);
  195. size_t minSize = 0;
  196. switch (format) {
  197. case WAVE_FORMAT_PCM:
  198. case WAVE_FORMAT_IEEE_FLOAT:
  199. minSize = 16;
  200. break;
  201. case WAVE_FORMAT_EXTENSIBLE:
  202. minSize = 40;
  203. break;
  204. default:
  205. #ifdef HAVE_STDERR
  206. ALOGE("unsupported format %u\n", format);
  207. #endif
  208. goto close;
  209. }
  210. if (chunkSize < minSize) {
  211. #ifdef HAVE_STDERR
  212. ALOGE("chunkSize %u < minSize %zu\n", chunkSize, minSize);
  213. #endif
  214. goto close;
  215. }
  216. actual = handle->callback.read(&fmt[2], sizeof(char), minSize - 2, stream);
  217. if (actual != minSize - 2) {
  218. #ifdef HAVE_STDERR
  219. ALOGE("actual %zu != %zu\n", actual, minSize - 16);
  220. #endif
  221. goto close;
  222. }
  223. if (chunkSize > minSize) {
  224. handle->callback.seek(stream, (long) (chunkSize - minSize), SEEK_CUR);
  225. }
  226. unsigned channels = little2u(&fmt[2]);
  227. // FIXME FCC_8
  228. if (channels != 1 && channels != 2 && channels != 4 && channels != 6 && channels != 8) {
  229. #ifdef HAVE_STDERR
  230. ALOGE("unsupported channels %u\n", channels);
  231. #endif
  232. goto close;
  233. }
  234. unsigned samplerate = little4u(&fmt[4]);
  235. if (samplerate == 0) {
  236. #ifdef HAVE_STDERR
  237. ALOGE("samplerate %u == 0\n", samplerate);
  238. #endif
  239. goto close;
  240. }
  241. // ignore byte rate
  242. // ignore block alignment
  243. unsigned bitsPerSample = little2u(&fmt[14]);
  244. if (bitsPerSample != 8 && bitsPerSample != 16 && bitsPerSample != 24 &&
  245. bitsPerSample != 32) {
  246. #ifdef HAVE_STDERR
  247. ALOGE("bitsPerSample %u != 8 or 16 or 24 or 32\n", bitsPerSample);
  248. #endif
  249. goto close;
  250. }
  251. unsigned bytesPerFrame = (bitsPerSample >> 3) * channels;
  252. handle->bytesPerFrame = bytesPerFrame;
  253. handle->info.samplerate = samplerate;
  254. handle->info.channels = channels;
  255. switch (bitsPerSample) {
  256. case 8:
  257. handle->info.format |= SF_FORMAT_PCM_U8;
  258. break;
  259. case 16:
  260. handle->info.format |= SF_FORMAT_PCM_16;
  261. break;
  262. case 24:
  263. handle->info.format |= SF_FORMAT_PCM_24;
  264. break;
  265. case 32:
  266. if (format == WAVE_FORMAT_IEEE_FLOAT)
  267. handle->info.format |= SF_FORMAT_FLOAT;
  268. else
  269. handle->info.format |= SF_FORMAT_PCM_32;
  270. break;
  271. }
  272. hadFmt = 1;
  273. } else if (!memcmp(&chunk[0], "data", 4)) {
  274. if (!hadFmt) {
  275. #ifdef HAVE_STDERR
  276. ALOGE("data not preceded by fmt\n");
  277. #endif
  278. goto close;
  279. }
  280. if (hadData) {
  281. #ifdef HAVE_STDERR
  282. ALOGE("multiple data\n");
  283. #endif
  284. goto close;
  285. }
  286. handle->remaining = chunkSize / handle->bytesPerFrame;
  287. handle->info.frames = handle->remaining;
  288. dataTell = handle->callback.tell(stream);
  289. if (chunkSize > 0) {
  290. handle->callback.seek(stream, (long) chunkSize, SEEK_CUR);
  291. }
  292. hadData = 1;
  293. } else if (!memcmp(&chunk[0], "fact", 4)) {
  294. // ignore fact
  295. if (chunkSize > 0) {
  296. handle->callback.seek(stream, (long) chunkSize, SEEK_CUR);
  297. }
  298. } else {
  299. // ignore unknown chunk
  300. #ifdef HAVE_STDERR
  301. ALOGE("ignoring unknown chunk %c%c%c%c\n",
  302. chunk[0], chunk[1], chunk[2], chunk[3]);
  303. #endif
  304. if (chunkSize > 0) {
  305. handle->callback.seek(stream, (long) chunkSize, SEEK_CUR);
  306. }
  307. }
  308. remaining -= chunkSize;
  309. }
  310. if (remaining > 0) {
  311. #ifdef HAVE_STDERR
  312. ALOGE("partial chunk at end of RIFF, remaining %zu\n", remaining);
  313. #endif
  314. goto close;
  315. }
  316. if (!hadData) {
  317. #ifdef HAVE_STDERR
  318. ALOGE("missing data\n");
  319. #endif
  320. goto close;
  321. }
  322. (void) handle->callback.seek(stream, dataTell, SEEK_SET);
  323. *info = handle->info;
  324. return handle;
  325. close:
  326. free(handle);
  327. handle->callback.close(stream);
  328. return NULL;
  329. }
  330. void sf_close(SNDFILE *handle)
  331. {
  332. if (handle == NULL)
  333. return;
  334. free(handle->temp);
  335. (void) handle->callback.close(handle->stream);
  336. free(handle);
  337. }
  338. sf_count_t sf_readf_short(SNDFILE *handle, short *ptr, sf_count_t desiredFrames)
  339. {
  340. if (handle == NULL || ptr == NULL || !handle->remaining ||
  341. desiredFrames <= 0) {
  342. return 0;
  343. }
  344. if (handle->remaining < (size_t) desiredFrames) {
  345. desiredFrames = handle->remaining;
  346. }
  347. // does not check for numeric overflow
  348. size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
  349. size_t actualBytes;
  350. void *temp = NULL;
  351. unsigned format = handle->info.format & SF_FORMAT_SUBMASK;
  352. if (format == SF_FORMAT_PCM_32 || format == SF_FORMAT_FLOAT || format == SF_FORMAT_PCM_24) {
  353. temp = malloc(desiredBytes);
  354. actualBytes = handle->callback.read(temp, sizeof(char), desiredBytes, handle->stream);
  355. } else {
  356. actualBytes = handle->callback.read(ptr, sizeof(char), desiredBytes, handle->stream);
  357. }
  358. size_t actualFrames = actualBytes / handle->bytesPerFrame;
  359. handle->remaining -= actualFrames;
  360. switch (format) {
  361. case SF_FORMAT_PCM_U8:
  362. memcpy_to_i16_from_u8(ptr, (unsigned char *) ptr, actualFrames * handle->info.channels);
  363. break;
  364. case SF_FORMAT_PCM_16:
  365. if (!isLittleEndian())
  366. my_swab(ptr, actualFrames * handle->info.channels);
  367. break;
  368. case SF_FORMAT_PCM_32:
  369. memcpy_to_i16_from_i32(ptr, (const int *) temp, actualFrames * handle->info.channels);
  370. free(temp);
  371. break;
  372. case SF_FORMAT_FLOAT:
  373. memcpy_to_i16_from_float(ptr, (const float *) temp, actualFrames * handle->info.channels);
  374. free(temp);
  375. break;
  376. case SF_FORMAT_PCM_24:
  377. memcpy_to_i16_from_p24(ptr, (const uint8_t *) temp, actualFrames * handle->info.channels);
  378. free(temp);
  379. break;
  380. default:
  381. memset(ptr, 0, actualFrames * handle->info.channels * sizeof(short));
  382. break;
  383. }
  384. return actualFrames;
  385. }
  386. /*
  387. sf_count_t sf_readf_float(SNDFILE *handle, float *ptr, sf_count_t desiredFrames)
  388. {
  389. if (handle == NULL || ptr == NULL || !handle->remaining ||
  390. desiredFrames <= 0) {
  391. return 0;
  392. }
  393. if (handle->remaining < (size_t) desiredFrames) {
  394. desiredFrames = handle->remaining;
  395. }
  396. // does not check for numeric overflow
  397. size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
  398. size_t actualBytes;
  399. void *temp = NULL;
  400. unsigned format = handle->info.format & SF_FORMAT_SUBMASK;
  401. if (format == SF_FORMAT_PCM_16 || format == SF_FORMAT_PCM_U8 || format == SF_FORMAT_PCM_24) {
  402. temp = malloc(desiredBytes);
  403. actualBytes = handle->callback.read(temp, sizeof(char), desiredBytes, handle->stream);
  404. } else {
  405. actualBytes = handle->callback.read(ptr, sizeof(char), desiredBytes, handle->stream);
  406. }
  407. size_t actualFrames = actualBytes / handle->bytesPerFrame;
  408. handle->remaining -= actualFrames;
  409. switch (format) {
  410. case SF_FORMAT_PCM_U8:
  411. #if 0
  412. // TODO - implement
  413. memcpy_to_float_from_u8(ptr, (const unsigned char *) temp,
  414. actualFrames * handle->info.channels);
  415. #endif
  416. free(temp);
  417. break;
  418. case SF_FORMAT_PCM_16:
  419. memcpy_to_float_from_i16(ptr, (const short *) temp, actualFrames * handle->info.channels);
  420. free(temp);
  421. break;
  422. case SF_FORMAT_PCM_32:
  423. memcpy_to_float_from_i32(ptr, (const int *) ptr, actualFrames * handle->info.channels);
  424. break;
  425. case SF_FORMAT_FLOAT:
  426. break;
  427. case SF_FORMAT_PCM_24:
  428. memcpy_to_float_from_p24(ptr, (const uint8_t *) temp, actualFrames * handle->info.channels);
  429. free(temp);
  430. break;
  431. default:
  432. memset(ptr, 0, actualFrames * handle->info.channels * sizeof(float));
  433. break;
  434. }
  435. return actualFrames;
  436. }
  437. sf_count_t sf_readf_int(SNDFILE *handle, int *ptr, sf_count_t desiredFrames)
  438. {
  439. if (handle == NULL || ptr == NULL || !handle->remaining ||
  440. desiredFrames <= 0) {
  441. return 0;
  442. }
  443. if (handle->remaining < (size_t) desiredFrames) {
  444. desiredFrames = handle->remaining;
  445. }
  446. // does not check for numeric overflow
  447. size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
  448. void *temp = NULL;
  449. unsigned format = handle->info.format & SF_FORMAT_SUBMASK;
  450. size_t actualBytes;
  451. if (format == SF_FORMAT_PCM_16 || format == SF_FORMAT_PCM_U8 || format == SF_FORMAT_PCM_24) {
  452. temp = malloc(desiredBytes);
  453. actualBytes = handle->callback.read(temp, sizeof(char), desiredBytes, handle->stream);
  454. } else {
  455. actualBytes = handle->callback.read(ptr, sizeof(char), desiredBytes, handle->stream);
  456. }
  457. size_t actualFrames = actualBytes / handle->bytesPerFrame;
  458. handle->remaining -= actualFrames;
  459. switch (format) {
  460. case SF_FORMAT_PCM_U8:
  461. #if 0
  462. // TODO - implement
  463. memcpy_to_i32_from_u8(ptr, (const unsigned char *) temp,
  464. actualFrames * handle->info.channels);
  465. #endif
  466. free(temp);
  467. break;
  468. case SF_FORMAT_PCM_16:
  469. memcpy_to_i32_from_i16(ptr, (const short *) temp, actualFrames * handle->info.channels);
  470. free(temp);
  471. break;
  472. case SF_FORMAT_PCM_32:
  473. break;
  474. case SF_FORMAT_FLOAT:
  475. memcpy_to_i32_from_float(ptr, (const float *) ptr, actualFrames * handle->info.channels);
  476. break;
  477. case SF_FORMAT_PCM_24:
  478. memcpy_to_i32_from_p24(ptr, (const uint8_t *) temp, actualFrames * handle->info.channels);
  479. free(temp);
  480. break;
  481. default:
  482. memset(ptr, 0, actualFrames * handle->info.channels * sizeof(int));
  483. break;
  484. }
  485. return actualFrames;
  486. }
  487. */