wma.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. #include <rtthread.h>
  2. #include <dfs_posix.h>
  3. #include "libwma/asf.h"
  4. #include "libwma/wmadec.h"
  5. int packet_count=0;
  6. /* The output buffer containing the decoded samples (channels 0 and 1)
  7. BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2.
  8. */
  9. static rt_uint32_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS];
  10. /* NOTE: WMADecodeContext is 120152 bytes (on x86) */
  11. static WMADecodeContext wmadec;
  12. enum asf_error_e {
  13. ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */
  14. ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */
  15. ASF_ERROR_EOF = -3, /* unexpected end of file */
  16. ASF_ERROR_IO = -4, /* error reading or writing to file */
  17. ASF_ERROR_INVALID_LENGTH = -5, /* length value conflict in input data */
  18. ASF_ERROR_INVALID_VALUE = -6, /* other value conflict in input data */
  19. ASF_ERROR_INVALID_OBJECT = -7, /* ASF object missing or in wrong place */
  20. ASF_ERROR_OBJECT_SIZE = -8, /* invalid ASF object size (too small) */
  21. ASF_ERROR_SEEKABLE = -9, /* file not seekable */
  22. ASF_ERROR_SEEK = -10, /* file is seekable but seeking failed */
  23. ASF_ERROR_ENCRYPTED = -11 /* file is encrypted */
  24. };
  25. // #define DEBUGF rt_kprintf
  26. #ifndef MIN
  27. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  28. #endif
  29. /* always little endian */
  30. #define read_uint16le(stream,buf) stream_buffer_read((stream), (rt_uint8_t*)(buf), 2)
  31. #define read_uint32le(stream,buf) stream_buffer_read((stream), (rt_uint8_t*)(buf), 4)
  32. #define read_uint64le(stream,buf) stream_buffer_read((stream), (rt_uint8_t*)(buf), 8)
  33. #define ID3V2_BUF_SIZE 300
  34. struct id3_tag
  35. {
  36. char* title;
  37. char* artist;
  38. char* album;
  39. char* year_string;
  40. char* comment;
  41. char* genre_string;
  42. char* track_string;
  43. char* albumartist;
  44. char* composer;
  45. /* Musicbrainz Track ID */
  46. char* mb_track_id;
  47. int year;
  48. int tracknum;
  49. rt_uint32_t bitrate; /* bit rate */
  50. rt_uint32_t frequency; /* sample frequency */
  51. rt_uint32_t length; /* length */
  52. rt_size_t first_frame_offset; /* Byte offset to first real MP3 frame.
  53. Used for skipping leading garbage to
  54. avoid gaps between tracks. */
  55. rt_uint32_t frame_count; /* number of frames in the file (if VBR) */
  56. rt_size_t offset; /* bytes played */
  57. /* these following two fields are used for local buffering */
  58. char id3v2buf[ID3V2_BUF_SIZE];
  59. char id3v1buf[4][92];
  60. rt_uint32_t user_data; /* user data */
  61. };
  62. /* TODO: Just read the GUIDs into a 16-byte array, and use memcmp to compare */
  63. struct guid_s {
  64. rt_uint32_t v1;
  65. rt_uint16_t v2;
  66. rt_uint16_t v3;
  67. rt_uint8_t v4[8];
  68. };
  69. typedef struct guid_s guid_t;
  70. typedef long long rt_uint64_t;
  71. struct asf_object_s {
  72. guid_t guid;
  73. rt_uint64_t size;
  74. rt_uint64_t datalen;
  75. };
  76. typedef struct asf_object_s asf_object_t;
  77. static const guid_t asf_guid_null =
  78. {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
  79. /* top level object guids */
  80. static const guid_t asf_guid_header =
  81. {0x75B22630, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
  82. static const guid_t asf_guid_data =
  83. {0x75B22636, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
  84. static const guid_t asf_guid_index =
  85. {0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}};
  86. /* header level object guids */
  87. static const guid_t asf_guid_file_properties =
  88. {0x8cabdca1, 0xa947, 0x11cf, {0x8E, 0xe4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
  89. static const guid_t asf_guid_stream_properties =
  90. {0xB7DC0791, 0xA9B7, 0x11CF, {0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
  91. static const guid_t asf_guid_content_description =
  92. {0x75B22633, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
  93. static const guid_t asf_guid_extended_content_description =
  94. {0xD2D0A440, 0xE307, 0x11D2, {0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50}};
  95. static const guid_t asf_guid_content_encryption =
  96. {0x2211b3fb, 0xbd23, 0x11d2, {0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e}};
  97. static const guid_t asf_guid_extended_content_encryption =
  98. {0x298ae614, 0x2622, 0x4c17, {0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c}};
  99. /* stream type guids */
  100. static const guid_t asf_guid_stream_type_audio =
  101. {0xF8699E40, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
  102. #define STREAM_BUFFER_SIZE 1024
  103. struct stream_buffer
  104. {
  105. rt_uint32_t length;
  106. rt_uint32_t position; /* current position in the buffer */
  107. rt_uint8_t *buffer;
  108. rt_size_t buffer_size;
  109. /* file descriptor of this stream buffer */
  110. int fd;
  111. rt_bool_t eof;
  112. };
  113. struct stream_buffer* stream;
  114. struct id3_tag _id3;
  115. struct id3_tag* id3;
  116. rt_size_t stream_buffer_read(struct stream_buffer* stream, rt_uint8_t* ptr, rt_size_t len)
  117. {
  118. rt_size_t rest_bytes;
  119. if (stream->position + len > stream->length)
  120. {
  121. rest_bytes = stream->length - stream->position;
  122. memcpy(ptr, &stream->buffer[stream->position], rest_bytes);
  123. ptr += rest_bytes;
  124. /* read more buffer */
  125. stream->length = read(stream->fd, &stream->buffer[0], stream->buffer_size);
  126. if (stream->length < len - rest_bytes)
  127. {
  128. stream->position = stream->length;
  129. stream->eof = RT_TRUE;
  130. }
  131. else
  132. stream->position = len - rest_bytes;
  133. memcpy(ptr, &stream->buffer[0], stream->position);
  134. return rest_bytes + stream->position;
  135. }
  136. memcpy(ptr, &stream->buffer[stream->position], len);
  137. stream->position += len;
  138. return len;
  139. }
  140. void stream_buffer_advance(struct stream_buffer* stream, rt_size_t size)
  141. {
  142. if (stream->position + size < stream->length)
  143. {
  144. stream->position += size;
  145. return;
  146. }
  147. stream->position = size - (stream->length - stream->position);
  148. stream->length = read(stream->fd, stream->buffer, stream->buffer_size);
  149. if (stream->length < stream->position) stream->eof = RT_TRUE;
  150. };
  151. rt_uint8_t *stream_buffer_request(struct stream_buffer* stream, rt_size_t *r_size, rt_size_t size)
  152. {
  153. rt_size_t rest_bytes, read_bytes, read_result;
  154. if (size > stream->buffer_size) return RT_NULL; /* request size more than the buffer size */
  155. if (stream->position + size < stream->length)
  156. {
  157. *r_size = size;
  158. return &stream->buffer[stream->position];
  159. }
  160. /* read more data */
  161. rest_bytes = stream->length - stream->position;
  162. memmove(&stream->buffer[0], &stream->buffer[stream->position], rest_bytes);
  163. read_bytes = stream->buffer_size - rest_bytes;
  164. read_bytes = (read_bytes / 512) * 512; /* align to 512 */
  165. read_result = read(stream->fd, &stream->buffer[rest_bytes], read_bytes);
  166. stream->position = 0;
  167. stream->length = read_result + rest_bytes;
  168. *r_size = size;
  169. return &stream->buffer[0];
  170. }
  171. struct stream_buffer* stream_buffer_create(int fd)
  172. {
  173. struct stream_buffer* buffer = (struct stream_buffer*) rt_malloc(sizeof(struct stream_buffer));
  174. if (buffer != RT_NULL)
  175. {
  176. buffer->fd = fd;
  177. buffer->eof = RT_FALSE;
  178. buffer->length = 0;
  179. buffer->position = 0;
  180. buffer->buffer_size = STREAM_BUFFER_SIZE;
  181. buffer->buffer = rt_malloc(buffer->buffer_size);
  182. }
  183. return buffer;
  184. }
  185. void stream_buffer_close(struct stream_buffer* stream)
  186. {
  187. rt_free(stream->buffer);
  188. close(stream->fd);
  189. }
  190. static int asf_guid_match(const guid_t *guid1, const guid_t *guid2)
  191. {
  192. if((guid1->v1 != guid2->v1) ||
  193. (guid1->v2 != guid2->v2) ||
  194. (guid1->v3 != guid2->v3) ||
  195. (rt_memcmp(guid1->v4, guid2->v4, 8)))
  196. {
  197. return 0;
  198. }
  199. return 1;
  200. }
  201. /* Read the 16 byte GUID from a file */
  202. static void asf_readGUID(struct stream_buffer* stream, guid_t* guid)
  203. {
  204. read_uint32le(stream, &guid->v1);
  205. read_uint16le(stream, &guid->v2);
  206. read_uint16le(stream, &guid->v3);
  207. stream_buffer_read(stream, guid->v4, 8);
  208. }
  209. static void asf_read_object_header(asf_object_t *obj, struct stream_buffer* stream)
  210. {
  211. asf_readGUID(stream, &obj->guid);
  212. read_uint64le(stream, &obj->size);
  213. obj->datalen = 0;
  214. }
  215. /* Parse an integer from the extended content object - we always
  216. convert to an int, regardless of native format.
  217. */
  218. static int asf_intdecode(struct stream_buffer* stream, int type, int length)
  219. {
  220. rt_uint16_t tmp16;
  221. rt_uint32_t tmp32;
  222. rt_uint64_t tmp64;
  223. if (type==3) {
  224. read_uint32le(stream, &tmp32);
  225. stream_buffer_advance(stream,length - 4);
  226. return (int)tmp32;
  227. } else if (type==4) {
  228. read_uint64le(stream, &tmp64);
  229. stream_buffer_advance(stream,length - 8);
  230. return (int)tmp64;
  231. } else if (type == 5) {
  232. read_uint16le(stream, &tmp16);
  233. stream_buffer_advance(stream,length - 2);
  234. return (int)tmp16;
  235. }
  236. return 0;
  237. }
  238. #define MASK 0xC0 /* 11000000 */
  239. #define COMP 0x80 /* 10x */
  240. static const unsigned char utf8comp[6] =
  241. {
  242. 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
  243. };
  244. /* Encode a UCS value as UTF-8 and return a pointer after this UTF-8 char. */
  245. unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8)
  246. {
  247. int tail = 0;
  248. if (ucs > 0x7F)
  249. while (ucs >> (5*tail + 6))
  250. tail++;
  251. *utf8++ = (ucs >> (6*tail)) | utf8comp[tail];
  252. while (tail--)
  253. *utf8++ = ((ucs >> (6*tail)) & (MASK ^ 0xFF)) | COMP;
  254. return utf8;
  255. }
  256. /* Decode a LE utf16 string from a disk buffer into a fixed-sized
  257. utf8 buffer.
  258. */
  259. static void asf_utf16LEdecode(struct stream_buffer* stream,
  260. rt_uint16_t utf16bytes,
  261. unsigned char **utf8,
  262. int* utf8bytes)
  263. {
  264. unsigned long ucs;
  265. int n;
  266. unsigned char utf16buf[256];
  267. unsigned char* utf16 = utf16buf;
  268. unsigned char* newutf8;
  269. n = stream_buffer_read(stream, utf16buf, MIN(sizeof(utf16buf), utf16bytes));
  270. utf16bytes -= n;
  271. while (n > 0) {
  272. /* Check for a surrogate pair */
  273. if (utf16[1] >= 0xD8 && utf16[1] < 0xE0) {
  274. if (n < 4) {
  275. /* Run out of utf16 bytes, read some more */
  276. utf16buf[0] = utf16[0];
  277. utf16buf[1] = utf16[1];
  278. n = stream_buffer_read(stream, utf16buf + 2, MIN(sizeof(utf16buf)-2, utf16bytes));
  279. utf16 = utf16buf;
  280. utf16bytes -= n;
  281. n += 2;
  282. }
  283. if (n < 4) {
  284. /* Truncated utf16 string, abort */
  285. break;
  286. }
  287. ucs = 0x10000 + ((utf16[0] << 10) | ((utf16[1] - 0xD8) << 18)
  288. | utf16[2] | ((utf16[3] - 0xDC) << 8));
  289. utf16 += 4;
  290. n -= 4;
  291. } else {
  292. ucs = (utf16[0] | (utf16[1] << 8));
  293. utf16 += 2;
  294. n -= 2;
  295. }
  296. if (*utf8bytes > 6) {
  297. newutf8 = utf8encode(ucs, *utf8);
  298. *utf8bytes -= (newutf8 - *utf8);
  299. *utf8 += (newutf8 - *utf8);
  300. }
  301. /* We have run out of utf16 bytes, read more if available */
  302. if ((n == 0) && (utf16bytes > 0)) {
  303. n = stream_buffer_read(stream, utf16buf, MIN(sizeof(utf16buf), utf16bytes));
  304. utf16 = utf16buf;
  305. utf16bytes -= n;
  306. }
  307. }
  308. *utf8[0] = 0;
  309. --*utf8bytes;
  310. if (utf16bytes > 0) {
  311. /* Skip any remaining bytes */
  312. stream_buffer_advance(stream, utf16bytes);
  313. }
  314. return;
  315. }
  316. static int asf_parse_header(struct stream_buffer* stream, struct id3_tag* id3,
  317. asf_waveformatex_t* wfx)
  318. {
  319. asf_object_t current;
  320. asf_object_t header;
  321. rt_uint64_t datalen;
  322. int i;
  323. int fileprop = 0;
  324. rt_uint64_t play_duration;
  325. rt_uint16_t flags;
  326. rt_uint32_t subobjects;
  327. rt_uint8_t utf8buf[512];
  328. int id3buf_remaining = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
  329. unsigned char* id3buf = (unsigned char*)id3->id3v2buf;
  330. asf_read_object_header((asf_object_t *) &header, stream);
  331. DEBUGF("header.size=%d\n",(int)header.size);
  332. if (header.size < 30) {
  333. /* invalid size for header object */
  334. return ASF_ERROR_OBJECT_SIZE;
  335. }
  336. read_uint32le(stream, &subobjects);
  337. /* Two reserved bytes - do we need to read them? */
  338. stream_buffer_advance(stream, 2);
  339. DEBUGF("Read header - size=%d, subobjects=%d\n",(int)header.size, (int)subobjects);
  340. if (subobjects > 0) {
  341. header.datalen = header.size - 30;
  342. /* TODO: Check that we have datalen bytes left in the file */
  343. datalen = header.datalen;
  344. for (i=0; i<(int)subobjects; i++) {
  345. DEBUGF("Parsing header object %d - datalen=%d\n",i,(int)datalen);
  346. if (datalen < 24) {
  347. DEBUGF("not enough data for reading object\n");
  348. break;
  349. }
  350. asf_read_object_header(&current, stream);
  351. if (current.size > datalen || current.size < 24) {
  352. DEBUGF("invalid object size - current.size=%d, datalen=%d\n",(int)current.size,(int)datalen);
  353. break;
  354. }
  355. if (asf_guid_match(&current.guid, &asf_guid_file_properties)) {
  356. if (current.size < 104)
  357. return ASF_ERROR_OBJECT_SIZE;
  358. if (fileprop) {
  359. /* multiple file properties objects not allowed */
  360. return ASF_ERROR_INVALID_OBJECT;
  361. }
  362. fileprop = 1;
  363. /* All we want is the play duration - uint64_t at offset 40 */
  364. stream_buffer_advance(stream, 40);
  365. read_uint64le(stream, &play_duration);
  366. id3->length = play_duration / 10000;
  367. DEBUGF("****** length = %lums\n", id3->length);
  368. /* Read the packet size - uint32_t at offset 68 */
  369. stream_buffer_advance(stream, 20);
  370. read_uint32le(stream, &wfx->packet_size);
  371. /* Skip bytes remaining in object */
  372. stream_buffer_advance(stream, current.size - 24 - 72);
  373. } else if (asf_guid_match(&current.guid, &asf_guid_stream_properties)) {
  374. guid_t guid;
  375. rt_uint32_t propdatalen;
  376. if (current.size < 78)
  377. return ASF_ERROR_OBJECT_SIZE;
  378. asf_readGUID(stream, &guid);
  379. stream_buffer_advance(stream, 24);
  380. read_uint32le(stream, &propdatalen);
  381. stream_buffer_advance(stream, 4);
  382. read_uint16le(stream, &flags);
  383. if (!asf_guid_match(&guid, &asf_guid_stream_type_audio)) {
  384. DEBUGF("Found stream properties for non audio stream, skipping\n");
  385. stream_buffer_advance(stream,current.size - 24 - 50);
  386. } else if (wfx->audiostream == -1) {
  387. stream_buffer_advance(stream, 4);
  388. DEBUGF("Found stream properties for audio stream %d\n",flags&0x7f);
  389. if (propdatalen < 18) {
  390. return ASF_ERROR_INVALID_LENGTH;
  391. }
  392. read_uint16le(stream, &wfx->codec_id);
  393. read_uint16le(stream, &wfx->channels);
  394. read_uint32le(stream, &wfx->rate);
  395. read_uint32le(stream, &wfx->bitrate);
  396. wfx->bitrate *= 8;
  397. read_uint16le(stream, &wfx->blockalign);
  398. read_uint16le(stream, &wfx->bitspersample);
  399. read_uint16le(stream, &wfx->datalen);
  400. /* Round bitrate to the nearest kbit */
  401. id3->bitrate = (wfx->bitrate + 500) / 1000;
  402. id3->frequency = wfx->rate;
  403. if (wfx->codec_id == ASF_CODEC_ID_WMAV1) {
  404. stream_buffer_read(stream, wfx->data, 4);
  405. stream_buffer_advance(stream, current.size - 24 - 72 - 4);
  406. wfx->audiostream = flags&0x7f;
  407. } else if (wfx->codec_id == ASF_CODEC_ID_WMAV2) {
  408. stream_buffer_read(stream, wfx->data, 6);
  409. stream_buffer_advance(stream,current.size - 24 - 72 - 6);
  410. wfx->audiostream = flags&0x7f;
  411. } else {
  412. DEBUGF("Unsupported WMA codec (Pro, Lossless, Voice, etc)\n");
  413. stream_buffer_advance(stream,current.size - 24 - 72);
  414. }
  415. }
  416. } else if (asf_guid_match(&current.guid, &asf_guid_content_description)) {
  417. /* Object contains five 16-bit string lengths, followed by the five strings:
  418. title, artist, copyright, description, rating
  419. */
  420. rt_uint16_t strlength[5];
  421. int i;
  422. DEBUGF("Found GUID_CONTENT_DESCRIPTION - size=%d\n",(int)(current.size - 24));
  423. /* Read the 5 string lengths - number of bytes included trailing zero */
  424. for (i=0; i<5; i++) {
  425. read_uint16le(stream, &strlength[i]);
  426. DEBUGF("strlength = %u\n",strlength[i]);
  427. }
  428. if (strlength[0] > 0) { /* 0 - Title */
  429. id3->title = id3buf;
  430. asf_utf16LEdecode(stream, strlength[0], &id3buf, &id3buf_remaining);
  431. }
  432. if (strlength[1] > 0) { /* 1 - Artist */
  433. id3->artist = id3buf;
  434. asf_utf16LEdecode(stream, strlength[1], &id3buf, &id3buf_remaining);
  435. }
  436. stream_buffer_advance(stream, strlength[2]); /* 2 - copyright */
  437. if (strlength[3] > 0) { /* 3 - description */
  438. id3->comment = id3buf;
  439. asf_utf16LEdecode(stream, strlength[3], &id3buf, &id3buf_remaining);
  440. }
  441. stream_buffer_advance(stream, strlength[4]); /* 4 - rating */
  442. } else if (asf_guid_match(&current.guid, &asf_guid_extended_content_description)) {
  443. rt_uint16_t count;
  444. int i;
  445. int bytesleft = current.size - 24;
  446. DEBUGF("Found GUID_EXTENDED_CONTENT_DESCRIPTION\n");
  447. read_uint16le(stream, &count);
  448. bytesleft -= 2;
  449. DEBUGF("extended metadata count = %u\n",count);
  450. for (i=0; i < count; i++) {
  451. rt_uint16_t length, type;
  452. unsigned char* utf8 = utf8buf;
  453. int utf8length = 512;
  454. read_uint16le(stream, &length);
  455. asf_utf16LEdecode(stream, length, &utf8, &utf8length);
  456. bytesleft -= 2 + length;
  457. read_uint16le(stream, &type);
  458. read_uint16le(stream, &length);
  459. if (!strcmp("WM/TrackNumber",utf8buf)) {
  460. if (type == 0) {
  461. id3->track_string = id3buf;
  462. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  463. id3->tracknum = atoi(id3->track_string);
  464. } else if ((type >=2) && (type <= 5)) {
  465. id3->tracknum = asf_intdecode(stream, type, length);
  466. } else {
  467. stream_buffer_advance(stream, length);
  468. }
  469. } else if ((!strcmp("WM/Genre",utf8buf)) && (type == 0)) {
  470. id3->genre_string = id3buf;
  471. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  472. } else if ((!strcmp("WM/AlbumTitle",utf8buf)) && (type == 0)) {
  473. id3->album = id3buf;
  474. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  475. } else if ((!strcmp("WM/AlbumArtist",utf8buf)) && (type == 0)) {
  476. id3->albumartist = id3buf;
  477. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  478. } else if ((!strcmp("WM/Composer",utf8buf)) && (type == 0)) {
  479. id3->composer = id3buf;
  480. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  481. } else if (!strcmp("WM/Year",utf8buf)) {
  482. if (type == 0) {
  483. id3->year_string = id3buf;
  484. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  485. id3->year = atoi(id3->year_string);
  486. } else if ((type >=2) && (type <= 5)) {
  487. id3->year = asf_intdecode(stream, type, length);
  488. } else {
  489. stream_buffer_advance(stream, length);
  490. }
  491. } else if (!strncmp("replaygain_", utf8buf, 11)) {
  492. char* value = id3buf;
  493. int buf_len = id3buf_remaining;
  494. int len;
  495. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  496. len = 0; // parse_replaygain(utf8buf, value, id3, value, buf_len);
  497. if (len == 0) {
  498. /* Don't need to keep the value */
  499. id3buf = value;
  500. id3buf_remaining = buf_len;
  501. }
  502. } else if (!strcmp("MusicBrainz/Track Id", utf8buf)) {
  503. id3->mb_track_id = id3buf;
  504. asf_utf16LEdecode(stream, length, &id3buf, &id3buf_remaining);
  505. } else {
  506. stream_buffer_advance(stream, length);
  507. }
  508. bytesleft -= 4 + length;
  509. }
  510. stream_buffer_advance(stream, bytesleft);
  511. } else if (asf_guid_match(&current.guid, &asf_guid_content_encryption)
  512. || asf_guid_match(&current.guid, &asf_guid_extended_content_encryption)) {
  513. DEBUGF("File is encrypted\n");
  514. return ASF_ERROR_ENCRYPTED;
  515. } else {
  516. DEBUGF("Skipping %d bytes of object\n",(int)(current.size - 24));
  517. stream_buffer_advance(stream,current.size - 24);
  518. }
  519. DEBUGF("Parsed object - size = %d\n",(int)current.size);
  520. datalen -= current.size;
  521. }
  522. if (i != (int)subobjects || datalen != 0) {
  523. DEBUGF("header data doesn't match given subobject count\n");
  524. return ASF_ERROR_INVALID_VALUE;
  525. }
  526. DEBUGF("%d subobjects read successfully\n", i);
  527. }
  528. DEBUGF("header validated correctly\n");
  529. return 0;
  530. }
  531. rt_bool_t get_asf_metadata(struct stream_buffer* stream, struct id3_tag* id3)
  532. {
  533. int res;
  534. asf_object_t obj;
  535. asf_waveformatex_t* wfx;
  536. wfx = (asf_waveformatex_t*) rt_malloc(sizeof(asf_waveformatex_t));
  537. if (wfx == RT_NULL) return RT_FALSE;
  538. wfx->audiostream = -1;
  539. res = asf_parse_header(stream, id3, wfx);
  540. if (res < 0) {
  541. DEBUGF("ASF: parsing error - %d\n",res);
  542. return RT_FALSE;
  543. }
  544. if (wfx->audiostream == -1) {
  545. DEBUGF("ASF: No WMA streams found\n");
  546. rt_free(wfx);
  547. return RT_FALSE;
  548. }
  549. asf_read_object_header(&obj, stream);
  550. if (!asf_guid_match(&obj.guid, &asf_guid_data)) {
  551. DEBUGF("ASF: No data object found\n");
  552. rt_free(wfx);
  553. return RT_FALSE;
  554. }
  555. /* Store the current file position - no need to parse the header
  556. again in the codec. The +26 skips the rest of the data object
  557. header.
  558. */
  559. id3->first_frame_offset = 26;
  560. /* set wfx to user data */
  561. id3->user_data = (rt_uint32_t)wfx;
  562. return RT_TRUE;
  563. }
  564. /* Read an unaligned 32-bit little endian long from buffer. */
  565. static unsigned long get_long_le(void* buf)
  566. {
  567. unsigned char* p = (unsigned char*) buf;
  568. return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
  569. }
  570. /* Read an unaligned 16-bit little endian short from buffer. */
  571. static unsigned short get_short_le(void* buf)
  572. {
  573. unsigned char* p = (unsigned char*) buf;
  574. return p[0] | (p[1] << 8);
  575. }
  576. #define GETLEN2b(bits) (((bits) == 0x03) ? 4 : bits)
  577. #define GETVALUE2b(bits, data) \
  578. (((bits) != 0x03) ? ((bits) != 0x02) ? ((bits) != 0x01) ? \
  579. 0 : *(data) : get_short_le(data) : get_long_le(data))
  580. static int asf_read_packet(rt_uint8_t** audiobuf, int* audiobufsize, int* packetlength, asf_waveformatex_t* wfx)
  581. {
  582. rt_uint8_t tmp8, packet_flags, packet_property;
  583. int stream_id;
  584. int ec_length, opaque_data, ec_length_type;
  585. int datalen;
  586. rt_uint8_t data[18];
  587. rt_uint8_t* datap;
  588. rt_uint32_t length;
  589. rt_uint32_t padding_length;
  590. rt_uint32_t send_time;
  591. rt_uint16_t duration;
  592. rt_uint16_t payload_count;
  593. int payload_length_type;
  594. rt_uint32_t payload_hdrlen;
  595. int payload_datalen;
  596. int multiple;
  597. rt_uint32_t replicated_length;
  598. rt_uint32_t media_object_number;
  599. rt_uint32_t media_object_offset;
  600. rt_uint32_t bytesread = 0;
  601. rt_uint8_t* buf;
  602. size_t bufsize;
  603. int i;
  604. /*DEBUGF("Reading new packet at %d bytes ", (int)ci->curpos);*/
  605. if (stream_buffer_read(stream, &tmp8, 1) == 0) {
  606. return ASF_ERROR_EOF;
  607. }
  608. bytesread++;
  609. /* TODO: We need a better way to detect endofstream */
  610. if (tmp8 != 0x82) {
  611. DEBUGF("Read failed: packet did not sync\n");
  612. return -1;
  613. }
  614. if (tmp8 & 0x80) {
  615. ec_length = tmp8 & 0x0f;
  616. opaque_data = (tmp8 >> 4) & 0x01;
  617. ec_length_type = (tmp8 >> 5) & 0x03;
  618. if (ec_length_type != 0x00 || opaque_data != 0 || ec_length != 0x02) {
  619. DEBUGF("incorrect error correction flags\n");
  620. return ASF_ERROR_INVALID_VALUE;
  621. }
  622. /* Skip ec_data */
  623. stream_buffer_advance(stream, ec_length);
  624. bytesread += ec_length;
  625. } else {
  626. ec_length = 0;
  627. }
  628. if (stream_buffer_read(stream, &packet_flags, 1) == 0) { return ASF_ERROR_EOF; }
  629. if (stream_buffer_read(stream, &packet_property, 1) == 0) { return ASF_ERROR_EOF; }
  630. bytesread += 2;
  631. datalen = GETLEN2b((packet_flags >> 1) & 0x03) +
  632. GETLEN2b((packet_flags >> 3) & 0x03) +
  633. GETLEN2b((packet_flags >> 5) & 0x03) + 6;
  634. if (stream_buffer_read(stream, data, datalen) == 0) {
  635. return ASF_ERROR_EOF;
  636. }
  637. bytesread += datalen;
  638. datap = data;
  639. length = GETVALUE2b((packet_flags >> 5) & 0x03, datap);
  640. datap += GETLEN2b((packet_flags >> 5) & 0x03);
  641. /* sequence value is not used */
  642. GETVALUE2b((packet_flags >> 1) & 0x03, datap);
  643. datap += GETLEN2b((packet_flags >> 1) & 0x03);
  644. padding_length = GETVALUE2b((packet_flags >> 3) & 0x03, datap);
  645. datap += GETLEN2b((packet_flags >> 3) & 0x03);
  646. send_time = get_long_le(datap);
  647. datap += 4;
  648. duration = get_short_le(datap);
  649. datap += 2;
  650. /*DEBUGF("and duration %d ms\n", duration);*/
  651. /* this is really idiotic, packet length can (and often will) be
  652. * undefined and we just have to use the header packet size as the size
  653. * value */
  654. if (!((packet_flags >> 5) & 0x03)) {
  655. length = wfx->packet_size;
  656. }
  657. /* this is also really idiotic, if packet length is smaller than packet
  658. * size, we need to manually add the additional bytes into padding length
  659. */
  660. if (length < wfx->packet_size) {
  661. padding_length += wfx->packet_size - length;
  662. length = wfx->packet_size;
  663. }
  664. if (length > wfx->packet_size) {
  665. DEBUGF("packet with too big length value\n");
  666. return ASF_ERROR_INVALID_LENGTH;
  667. }
  668. /* check if we have multiple payloads */
  669. if (packet_flags & 0x01) {
  670. if (stream_buffer_read(stream, &tmp8, 1) == 0) {
  671. return ASF_ERROR_EOF;
  672. }
  673. payload_count = tmp8 & 0x3f;
  674. payload_length_type = (tmp8 >> 6) & 0x03;
  675. bytesread++;
  676. } else {
  677. payload_count = 1;
  678. payload_length_type = 0x02; /* not used */
  679. }
  680. if (length < bytesread) {
  681. DEBUGF("header exceeded packet size, invalid file - length=%d, bytesread=%d\n",(int)length,(int)bytesread);
  682. /* FIXME: should this be checked earlier? */
  683. return ASF_ERROR_INVALID_LENGTH;
  684. }
  685. /* We now parse the individual payloads, and move all payloads
  686. belonging to our audio stream to a contiguous block, starting at
  687. the location of the first payload.
  688. */
  689. *audiobuf = NULL;
  690. *audiobufsize = 0;
  691. *packetlength = length - bytesread;
  692. buf = stream_buffer_request(stream, &bufsize, length);
  693. datap = buf;
  694. if (bufsize != length) {
  695. /* This should only happen with packets larger than 32KB (the
  696. guard buffer size). All the streams I've seen have
  697. relatively small packets less than about 8KB), but I don't
  698. know what is expected.
  699. */
  700. DEBUGF("Could not read packet (requested %d bytes, received %d), aborting\n",
  701. (int)length,(int)bufsize);
  702. return -1;
  703. }
  704. for (i=0; i<payload_count; i++) {
  705. stream_id = datap[0]&0x7f;
  706. datap++;
  707. bytesread++;
  708. payload_hdrlen = GETLEN2b(packet_property & 0x03) +
  709. GETLEN2b((packet_property >> 2) & 0x03) +
  710. GETLEN2b((packet_property >> 4) & 0x03);
  711. //DEBUGF("payload_hdrlen = %d\n",payload_hdrlen);
  712. if (payload_hdrlen > sizeof(data)) {
  713. DEBUGF("Unexpectedly long datalen in data - %d\n",datalen);
  714. return ASF_ERROR_OUTOFMEM;
  715. }
  716. bytesread += payload_hdrlen;
  717. media_object_number = GETVALUE2b((packet_property >> 4) & 0x03, datap);
  718. datap += GETLEN2b((packet_property >> 4) & 0x03);
  719. media_object_offset = GETVALUE2b((packet_property >> 2) & 0x03, datap);
  720. datap += GETLEN2b((packet_property >> 2) & 0x03);
  721. replicated_length = GETVALUE2b(packet_property & 0x03, datap);
  722. datap += GETLEN2b(packet_property & 0x03);
  723. /* TODO: Validate replicated_length */
  724. /* TODO: Is the content of this important for us? */
  725. datap += replicated_length;
  726. bytesread += replicated_length;
  727. multiple = packet_flags & 0x01;
  728. if (multiple) {
  729. int x;
  730. x = GETLEN2b(payload_length_type);
  731. if (x != 2) {
  732. /* in multiple payloads datalen should be a word */
  733. return ASF_ERROR_INVALID_VALUE;
  734. }
  735. payload_datalen = GETVALUE2b(payload_length_type, datap);
  736. datap += x;
  737. bytesread += x;
  738. } else {
  739. payload_datalen = length - bytesread - padding_length;
  740. }
  741. if (replicated_length==1)
  742. datap++;
  743. if (stream_id == wfx->audiostream)
  744. {
  745. if (*audiobuf == NULL) {
  746. /* The first payload can stay where it is */
  747. *audiobuf = datap;
  748. *audiobufsize = payload_datalen;
  749. } else {
  750. /* The second and subsequent payloads in this packet
  751. that belong to the audio stream need to be moved to be
  752. contiguous with the first payload.
  753. */
  754. memmove(*audiobuf + *audiobufsize, datap, payload_datalen);
  755. *audiobufsize += payload_datalen;
  756. }
  757. }
  758. datap += payload_datalen;
  759. bytesread += payload_datalen;
  760. }
  761. if (*audiobuf != NULL)
  762. return 1;
  763. else
  764. return 0;
  765. }
  766. #include <finsh.h>
  767. /* this is the codec entry point */
  768. void wma(const char* filename)
  769. {
  770. rt_uint32_t elapsedtime;
  771. asf_waveformatex_t* wfx;
  772. int i;
  773. int wmares, res;
  774. rt_uint8_t* audiobuf;
  775. int audiobufsize;
  776. int packetlength = 0;
  777. int errcount = 0;
  778. rt_device_t snd = RT_NULL;
  779. int fd;
  780. snd = rt_device_find("snd");
  781. if (snd == RT_NULL)
  782. {
  783. rt_kprintf("open audio device failed\n");
  784. return;
  785. }
  786. rt_device_open(snd, RT_DEVICE_OFLAG_RDONLY);
  787. fd = open(filename, O_RDONLY, 0);
  788. if (fd < 0)
  789. {
  790. rt_kprintf("open file: %s failed\n", filename);
  791. return ;
  792. }
  793. /* create stream */
  794. stream = stream_buffer_create(fd);
  795. id3 = &_id3;
  796. /* get meta information */
  797. get_asf_metadata(stream, id3);
  798. wfx = (asf_waveformatex_t*)id3->user_data;
  799. if (wma_decode_init(&wmadec, wfx) < 0) {
  800. DEBUGF("WMA: Unsupported or corrupt file\n");
  801. goto exit;
  802. }
  803. DEBUGF("**************** IN WMA.C ******************\n");
  804. /* The main decoding loop */
  805. res = 1;
  806. while (res >= 0)
  807. {
  808. errcount = 0;
  809. new_packet:
  810. res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, wfx);
  811. if (res < 0) {
  812. /* We'll try to recover from a parse error a certain number of
  813. * times. If we succeed, the error counter will be reset.
  814. */
  815. errcount++;
  816. DEBUGF("read_packet error %d, errcount %d\n",wmares, errcount);
  817. if (errcount > 5) {
  818. goto done;
  819. } else {
  820. stream_buffer_advance(stream, packetlength);
  821. goto new_packet;
  822. }
  823. } else if (res > 0) {
  824. wma_decode_superframe_init(&wmadec, audiobuf, audiobufsize);
  825. for (i=0; i < wmadec.nb_frames; i++)
  826. {
  827. wmares = wma_decode_superframe_frame(&wmadec,
  828. decoded,
  829. audiobuf, audiobufsize);
  830. if (wmares < 0) {
  831. /* Do the above, but for errors in decode. */
  832. errcount++;
  833. DEBUGF("WMA decode error %d, errcount %d\n",wmares, errcount);
  834. if (errcount > 5) {
  835. goto done;
  836. } else {
  837. stream_buffer_advance(stream, packetlength);
  838. goto new_packet;
  839. }
  840. } else if (wmares > 0) {
  841. /* write to audio device */
  842. elapsedtime += (wmares*10)/(wfx->rate/100);
  843. // ci->set_elapsed(elapsedtime);
  844. }
  845. }
  846. }
  847. stream_buffer_advance(stream, packetlength);
  848. }
  849. done:
  850. exit:
  851. stream_buffer_close(stream);
  852. stream = RT_NULL;
  853. return ;
  854. }
  855. FINSH_FUNCTION_EXPORT(wma, wma decode test)