mp3.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. static int try_get_bitrate(unsigned char *buf, int buf_size)
  21. {
  22. int offs1, offs = 0;
  23. int ret;
  24. while (1)
  25. {
  26. offs1 = mp3_find_sync_word(buf + offs, buf_size - offs);
  27. if (offs1 < 0)
  28. return -2;
  29. offs += offs1;
  30. if (buf_size - offs < 4)
  31. return -3;
  32. // printf("trying header %08x\n", *(int *)(buf + offs));
  33. ret = mpeg1_l3_bitrates[buf[offs + 2] >> 4];
  34. if (ret > 0)
  35. return ret;
  36. }
  37. return -2;
  38. }
  39. int mp3_get_bitrate(void *f_, int len)
  40. {
  41. unsigned char buf[2048];
  42. FILE *f = f_;
  43. int retval = -1;
  44. int ret;
  45. memset(buf, 0, sizeof(buf));
  46. fseek(f, 0, SEEK_SET);
  47. ret = fread(buf, 1, sizeof(buf), f);
  48. if (ret != sizeof(buf))
  49. goto out;
  50. ret = try_get_bitrate(buf, sizeof(buf));
  51. if (ret <= 0) {
  52. // try to read somewhere around the middle
  53. fseek(f, len / 2, SEEK_SET);
  54. ret = fread(buf, 1, sizeof(buf), f);
  55. if (ret == sizeof(buf))
  56. ret = try_get_bitrate(buf, sizeof(buf));
  57. }
  58. if (ret > 0)
  59. retval = ret;
  60. //printf("bitrate: %i\n", retval);
  61. out:
  62. fseek(f, 0, SEEK_SET);
  63. return retval;
  64. }
  65. void mp3_start_play(void *f_, int pos1024)
  66. {
  67. unsigned char buf[2048];
  68. FILE *f = f_;
  69. int ret;
  70. mp3_file_len = mp3_file_pos = 0;
  71. mp3_current_file = NULL;
  72. cdda_out_pos = 0;
  73. decoder_active = 0;
  74. if (!(PicoIn.opt & POPT_EN_MCD_CDDA) || f == NULL) // cdda disabled or no file?
  75. return;
  76. fseek(f, 0, SEEK_END);
  77. mp3_file_len = ftell(f);
  78. // search for first sync word, skipping stuff like ID3 tags
  79. while (mp3_file_pos < 128*1024) {
  80. int offs, bytes;
  81. fseek(f, mp3_file_pos, SEEK_SET);
  82. bytes = fread(buf, 1, sizeof(buf), f);
  83. if (bytes < 4)
  84. break;
  85. offs = mp3_find_sync_word(buf, bytes);
  86. if (offs >= 0) {
  87. mp3_file_pos += offs;
  88. break;
  89. }
  90. mp3_file_pos += bytes - 3;
  91. }
  92. // seek..
  93. if (pos1024 != 0) {
  94. unsigned long long pos64 = mp3_file_len - mp3_file_pos;
  95. pos64 *= pos1024;
  96. mp3_file_pos += pos64 >> 10;
  97. }
  98. ret = mp3dec_start(f, mp3_file_pos);
  99. if (ret != 0) {
  100. return;
  101. }
  102. mp3_current_file = f;
  103. decoder_active = 1;
  104. mp3dec_decode(mp3_current_file, &mp3_file_pos, mp3_file_len);
  105. }
  106. void mp3_update(int *buffer, int length, int stereo)
  107. {
  108. int length_mp3, shr = 0;
  109. void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;
  110. if (mp3_current_file == NULL || mp3_file_pos >= mp3_file_len)
  111. return; /* no file / EOF */
  112. if (!decoder_active)
  113. return;
  114. length_mp3 = length;
  115. if (PicoIn.sndRate <= 11025 + 100) {
  116. mix_samples = mix_16h_to_32_s2;
  117. length_mp3 <<= 2; shr = 2;
  118. }
  119. else if (PicoIn.sndRate <= 22050 + 100) {
  120. mix_samples = mix_16h_to_32_s1;
  121. length_mp3 <<= 1; shr = 1;
  122. }
  123. if (1152 - cdda_out_pos >= length_mp3) {
  124. mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
  125. length * 2);
  126. cdda_out_pos += length_mp3;
  127. } else {
  128. int ret, left = 1152 - cdda_out_pos;
  129. if (left > 0)
  130. mix_samples(buffer, cdda_out_buffer + cdda_out_pos * 2,
  131. (left >> shr) * 2);
  132. ret = mp3dec_decode(mp3_current_file, &mp3_file_pos,
  133. mp3_file_len);
  134. if (ret == 0) {
  135. cdda_out_pos = length_mp3 - left;
  136. mix_samples(buffer + (left >> shr) * 2,
  137. cdda_out_buffer,
  138. (cdda_out_pos >> shr) * 2);
  139. } else
  140. cdda_out_pos = 0;
  141. }
  142. }