wavreader.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* ------------------------------------------------------------------
  2. * Copyright (C) 2009 Martin Storsjo
  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
  13. * express or implied.
  14. * See the License for the specific language governing permissions
  15. * and limitations under the License.
  16. * -------------------------------------------------------------------
  17. */
  18. #include "wavreader.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <stdint.h>
  23. #define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
  24. struct wav_reader {
  25. FILE *wav;
  26. uint32_t data_length;
  27. int format;
  28. int sample_rate;
  29. int bits_per_sample;
  30. int channels;
  31. int byte_rate;
  32. int block_align;
  33. int streamed;
  34. };
  35. static uint32_t read_tag(struct wav_reader* wr) {
  36. uint32_t tag = 0;
  37. tag = (tag << 8) | fgetc(wr->wav);
  38. tag = (tag << 8) | fgetc(wr->wav);
  39. tag = (tag << 8) | fgetc(wr->wav);
  40. tag = (tag << 8) | fgetc(wr->wav);
  41. return tag;
  42. }
  43. static uint32_t read_int32(struct wav_reader* wr) {
  44. uint32_t value = 0;
  45. value |= fgetc(wr->wav) << 0;
  46. value |= fgetc(wr->wav) << 8;
  47. value |= fgetc(wr->wav) << 16;
  48. value |= fgetc(wr->wav) << 24;
  49. return value;
  50. }
  51. static uint16_t read_int16(struct wav_reader* wr) {
  52. uint16_t value = 0;
  53. value |= fgetc(wr->wav) << 0;
  54. value |= fgetc(wr->wav) << 8;
  55. return value;
  56. }
  57. static void skip(FILE *f, int n) {
  58. int i;
  59. for (i = 0; i < n; i++)
  60. fgetc(f);
  61. }
  62. void* wav_read_open(const char *filename) {
  63. struct wav_reader* wr = (struct wav_reader*) malloc(sizeof(*wr));
  64. long data_pos = 0;
  65. memset(wr, 0, sizeof(*wr));
  66. if (!strcmp(filename, "-"))
  67. wr->wav = stdin;
  68. else
  69. wr->wav = fopen(filename, "rb");
  70. if (wr->wav == NULL) {
  71. free(wr);
  72. return NULL;
  73. }
  74. while (1) {
  75. uint32_t tag, tag2, length;
  76. tag = read_tag(wr);
  77. if (feof(wr->wav))
  78. break;
  79. length = read_int32(wr);
  80. if (!length || length >= 0x7fff0000) {
  81. wr->streamed = 1;
  82. length = ~0;
  83. }
  84. if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
  85. fseek(wr->wav, length, SEEK_CUR);
  86. continue;
  87. }
  88. tag2 = read_tag(wr);
  89. length -= 4;
  90. if (tag2 != TAG('W', 'A', 'V', 'E')) {
  91. fseek(wr->wav, length, SEEK_CUR);
  92. continue;
  93. }
  94. // RIFF chunk found, iterate through it
  95. while (length >= 8) {
  96. uint32_t subtag, sublength;
  97. subtag = read_tag(wr);
  98. if (feof(wr->wav))
  99. break;
  100. sublength = read_int32(wr);
  101. length -= 8;
  102. if (length < sublength)
  103. break;
  104. if (subtag == TAG('f', 'm', 't', ' ')) {
  105. if (sublength < 16) {
  106. // Insufficient data for 'fmt '
  107. break;
  108. }
  109. wr->format = read_int16(wr);
  110. wr->channels = read_int16(wr);
  111. wr->sample_rate = read_int32(wr);
  112. wr->byte_rate = read_int32(wr);
  113. wr->block_align = read_int16(wr);
  114. wr->bits_per_sample = read_int16(wr);
  115. if (wr->format == 0xfffe) {
  116. if (sublength < 28) {
  117. // Insufficient data for waveformatex
  118. break;
  119. }
  120. skip(wr->wav, 8);
  121. wr->format = read_int32(wr);
  122. skip(wr->wav, sublength - 28);
  123. } else {
  124. skip(wr->wav, sublength - 16);
  125. }
  126. } else if (subtag == TAG('d', 'a', 't', 'a')) {
  127. data_pos = ftell(wr->wav);
  128. wr->data_length = sublength;
  129. if (!wr->data_length || wr->streamed) {
  130. wr->streamed = 1;
  131. return wr;
  132. }
  133. fseek(wr->wav, sublength, SEEK_CUR);
  134. } else {
  135. skip(wr->wav, sublength);
  136. }
  137. length -= sublength;
  138. }
  139. if (length > 0) {
  140. // Bad chunk?
  141. fseek(wr->wav, length, SEEK_CUR);
  142. }
  143. }
  144. fseek(wr->wav, data_pos, SEEK_SET);
  145. return wr;
  146. }
  147. void wav_read_close(void* obj) {
  148. struct wav_reader* wr = (struct wav_reader*) obj;
  149. if (wr->wav != stdin)
  150. fclose(wr->wav);
  151. free(wr);
  152. }
  153. int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length) {
  154. struct wav_reader* wr = (struct wav_reader*) obj;
  155. if (format)
  156. *format = wr->format;
  157. if (channels)
  158. *channels = wr->channels;
  159. if (sample_rate)
  160. *sample_rate = wr->sample_rate;
  161. if (bits_per_sample)
  162. *bits_per_sample = wr->bits_per_sample;
  163. if (data_length)
  164. *data_length = wr->data_length;
  165. return wr->format && wr->sample_rate;
  166. }
  167. int wav_read_data(void* obj, unsigned char* data, unsigned int length) {
  168. struct wav_reader* wr = (struct wav_reader*) obj;
  169. int n;
  170. if (wr->wav == NULL)
  171. return -1;
  172. if (length > wr->data_length && !wr->streamed)
  173. length = wr->data_length;
  174. n = fread(data, 1, length, wr->wav);
  175. wr->data_length -= length;
  176. return n;
  177. }