mp3.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * PicoDrive
  3. * (C) notaz, 2010,2013
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. */
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <pico/pico_int.h>
  11. #include <pico/sound/mix.h>
  12. #include "mp3.h"
  13. static FILE *mp3_current_file;
  14. static int mp3_file_len, mp3_file_pos;
  15. static int cdda_out_pos;
  16. static int decoder_active;
  17. unsigned short mpeg1_l3_bitrates[16] = {
  18. 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
  19. };
  20. int mp3_find_sync_word(const unsigned char *buf, int size)
  21. {
  22. const unsigned char *p, *pe;
  23. /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
  24. for (p = buf, pe = buf + size - 3; p <= pe; p++)
  25. {
  26. int pn;
  27. if (p[0] != 0xff)
  28. continue;
  29. pn = p[1];
  30. if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
  31. (pn & 6) == 0) { // invalid layer
  32. p++; continue;
  33. }
  34. pn = p[2];
  35. if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
  36. (pn & 0x0c) != 0) { // not 44kHz
  37. continue;
  38. }
  39. return p - buf;
  40. }
  41. return -1;
  42. }
  43. static int try_get_bitrate(unsigned char *buf, int buf_size)
  44. {
  45. int offs1, offs = 0;
  46. int ret;
  47. while (1)
  48. {
  49. offs1 = mp3_find_sync_word(buf + offs, buf_size - offs);
  50. if (offs1 < 0)
  51. return -2;
  52. offs += offs1;
  53. if (buf_size - offs < 4)
  54. return -3;
  55. // printf("trying header %08x\n", *(int *)(buf + offs));
  56. ret = mpeg1_l3_bitrates[buf[offs + 2] >> 4];
  57. if (ret > 0)
  58. return ret;
  59. }
  60. return -2;
  61. }
  62. int mp3_get_bitrate(void *f_, int len)
  63. {
  64. unsigned char buf[2048];
  65. FILE *f = f_;
  66. int retval = -1;
  67. int ret;
  68. memset(buf, 0, sizeof(buf));
  69. fseek(f, 0, SEEK_SET);
  70. ret = fread(buf, 1, sizeof(buf), f);
  71. if (ret != sizeof(buf))
  72. goto out;
  73. ret = try_get_bitrate(buf, sizeof(buf));
  74. if (ret <= 0) {
  75. // try to read somewhere around the middle
  76. fseek(f, len / 2, SEEK_SET);
  77. fread(buf, 1, sizeof(buf), f);
  78. ret = try_get_bitrate(buf, sizeof(buf));
  79. }
  80. if (ret > 0)
  81. retval = ret;
  82. //printf("bitrate: %i\n", retval);
  83. out:
  84. fseek(f, 0, SEEK_SET);
  85. return retval;
  86. }
  87. void mp3_start_play(void *f_, int pos1024)
  88. {
  89. unsigned char buf[2048];
  90. FILE *f = f_;
  91. int ret;
  92. mp3_file_len = mp3_file_pos = 0;
  93. mp3_current_file = NULL;
  94. cdda_out_pos = 0;
  95. decoder_active = 0;
  96. if (!(PicoOpt & POPT_EN_MCD_CDDA) || f == NULL) // cdda disabled or no file?
  97. return;
  98. fseek(f, 0, SEEK_END);
  99. mp3_file_len = ftell(f);
  100. // search for first sync word, skipping stuff like ID3 tags
  101. while (mp3_file_pos < 128*1024) {
  102. int offs, bytes;
  103. fseek(f, mp3_file_pos, SEEK_SET);
  104. bytes = fread(buf, 1, sizeof(buf), f);
  105. if (bytes < 4)
  106. break;
  107. offs = mp3_find_sync_word(buf, bytes);
  108. if (offs >= 0) {
  109. mp3_file_pos += offs;
  110. break;
  111. }
  112. mp3_file_pos += bytes - 3;
  113. }
  114. // seek..
  115. if (pos1024 != 0) {
  116. unsigned long long pos64 = mp3_file_len - mp3_file_pos;
  117. pos64 *= pos1024;
  118. mp3_file_pos += pos64 >> 10;
  119. }
  120. ret = mp3dec_start(f, mp3_file_pos);
  121. if (ret != 0) {
  122. return;
  123. }
  124. mp3_current_file = f;
  125. decoder_active = 1;
  126. mp3dec_decode(mp3_current_file, &mp3_file_pos, mp3_file_len);
  127. }
  128. void mp3_update(int *buffer, int length, int stereo)
  129. {
  130. int length_mp3, shr = 0;
  131. void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;
  132. if (mp3_current_file == NULL || mp3_file_pos >= mp3_file_len)
  133. return; /* no file / EOF */
  134. if (!decoder_active)
  135. return;
  136. length_mp3 = length;
  137. if (PsndRate <= 11025 + 100) {
  138. mix_samples = mix_16h_to_32_s2;
  139. length_mp3 <<= 2; shr = 2;
  140. }
  141. else if (PsndRate <= 22050 + 100) {
  142. mix_samples = mix_16h_to_32_s1;
  143. length_mp3 <<= 1; shr = 1;
  144. }
  145. if (1152 - cdda_out_pos >= length_mp3) {
  146. mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
  147. length * 2);
  148. cdda_out_pos += length_mp3;
  149. } else {
  150. int ret, left = 1152 - cdda_out_pos;
  151. if (left > 0)
  152. mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
  153. (left >> shr) * 2);
  154. ret = mp3dec_decode(mp3_current_file, &mp3_file_pos,
  155. mp3_file_len);
  156. if (ret == 0) {
  157. cdda_out_pos = length_mp3 - left;
  158. mix_samples(buffer + (left >> shr) * 2,
  159. cdda_out_buffer,
  160. (cdda_out_pos >> shr) * 2);
  161. } else
  162. cdda_out_pos = 0;
  163. }
  164. }