1
0

LAMEinfo.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #include "LAMEinfo.h"
  2. #include <windows.h>
  3. #include <memory.h>
  4. #include <math.h>
  5. #include "api__in_mp3.h"
  6. #include "resource.h"
  7. #include "in2.h"
  8. #pragma intrinsic(memcmp)
  9. extern In_Module mod;
  10. // Xing header -
  11. // 4 Xing
  12. // 4 flags
  13. // 4 frames
  14. // 4 bytes
  15. // 100 toc
  16. // 4 bytes VBR quality
  17. // Lame tag
  18. // 9 bytes - release name
  19. // 11
  20. // Lame extended info tag
  21. // http://gabriel.mp3-tech.org/mp3infotag.html
  22. /*-------------------------------------------------------------*/
  23. static int32_t ExtractI4(unsigned char *buf)
  24. {
  25. int x;
  26. // big endian extract
  27. x = buf[0];
  28. x <<= 8;
  29. x |= buf[1];
  30. x <<= 8;
  31. x |= buf[2];
  32. x <<= 8;
  33. x |= buf[3];
  34. return x;
  35. }
  36. static int16_t ExtractI2(unsigned char *buf)
  37. {
  38. int x;
  39. // big endian extract
  40. x = buf[0];
  41. x <<= 8;
  42. x |= buf[1];
  43. return x;
  44. }
  45. const static int bitrateV1L3[] = { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0};
  46. const static int bitrateV1L1[] = { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0};
  47. const static int bitrateV1L2[] = { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0};
  48. const static int bitrateV2L1[] = { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0};
  49. const static int bitrateV2L2L3[] = { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0};
  50. const static int sampleRateV1[] = {44100, 48000, 32000, 0};
  51. const static int sampleRateV2[] = {22050, 24000, 16000, 0};
  52. const static int sampleRateV2_5[] = {11025, 12000, 8000, 0};
  53. // [mpeg_version][layer]
  54. static const int samples_per_frame[4][4] =
  55. {
  56. // Layer 3, Layer 2, Layer 1
  57. { 0, 576, 1152, 384}, // MPEG2.5
  58. { 0, },
  59. { 0, 576, 1152, 384}, // MPEG2
  60. { 0, 1152, 1152, 384}, // MPEG1
  61. };
  62. void MPEGFrame::ReadBuffer(const unsigned char *buffer)
  63. {
  64. sync = ((unsigned short)buffer[0] << 3) | (buffer[1] >> 5);
  65. mpegVersion = (buffer[1] >> 3) & 3;
  66. layer = (buffer[1] >> 1) & 3;
  67. protection = (buffer[1]) & 1;
  68. bitrateIndex = (buffer[2] >> 4) & 0xF;
  69. sampleRateIndex = (buffer[2] >> 2) & 3;
  70. paddingBit = (buffer[2] >> 1) & 1;
  71. privateBit = buffer[2] & 1;
  72. channelMode = (buffer[3] >> 6) & 3;
  73. modeExtension = (buffer[3] >> 4) & 3;
  74. copyright = (buffer[3] >> 3) & 1;
  75. original = (buffer[3] >> 2) & 1;
  76. emphasis = (buffer[3]) & 3;
  77. }
  78. bool MPEGFrame::IsSync()
  79. {
  80. return sync == 0x07FF
  81. && layer != LayerError
  82. && mpegVersion != MPEG_Error
  83. && bitrateIndex != 15
  84. && bitrateIndex != 0
  85. && sampleRateIndex != 3
  86. && !(mpegVersion == MPEG2 && layer != Layer3)
  87. && !(mpegVersion == MPEG2_5 && layer != Layer3);
  88. }
  89. int MPEGFrame::GetBitrate()
  90. {
  91. switch (mpegVersion)
  92. {
  93. case MPEG1:
  94. switch (layer)
  95. {
  96. case Layer1:
  97. return bitrateV1L1[bitrateIndex];
  98. case Layer2:
  99. return bitrateV1L2[bitrateIndex];
  100. case Layer3:
  101. return bitrateV1L3[bitrateIndex];
  102. }
  103. break;
  104. case MPEG2:
  105. case MPEG2_5:
  106. switch (layer)
  107. {
  108. case Layer1:
  109. return bitrateV2L1[bitrateIndex];
  110. case Layer2:
  111. case Layer3:
  112. return bitrateV2L2L3[bitrateIndex];
  113. }
  114. break;
  115. }
  116. return 0; // shouldn't get here
  117. }
  118. int MPEGFrame::GetPadding()
  119. {
  120. if (paddingBit == NotPadded)
  121. return 0;
  122. if (layer == Layer1)
  123. return 4;
  124. else
  125. return 1;
  126. }
  127. int MPEGFrame::HeaderSize()
  128. {
  129. if (protection == CRC)
  130. return 4 + 2; // 32bits frame header, 16bits CRC
  131. else
  132. return 4; // 32bits frame ehader
  133. }
  134. int MPEGFrame::GetSampleRate() const
  135. {
  136. switch(mpegVersion)
  137. {
  138. case MPEG1: return sampleRateV1[sampleRateIndex];
  139. case MPEG2:return sampleRateV2[sampleRateIndex];
  140. case MPEG2_5:return sampleRateV2_5[sampleRateIndex];
  141. default: return 99999999; // return something that will hopefully cause the framesize to be 0
  142. }
  143. }
  144. int MPEGFrame::GetSamplesPerFrame() const
  145. {
  146. return samples_per_frame[mpegVersion][layer];
  147. }
  148. bool MPEGFrame::IsCopyright()
  149. {
  150. return copyright == 1;
  151. }
  152. bool MPEGFrame::IsCRC()
  153. {
  154. return protection == CRC;
  155. }
  156. bool MPEGFrame::IsOriginal()
  157. {
  158. return original == 1;
  159. }
  160. const char *MPEGFrame::GetEmphasisString()
  161. {
  162. static char tempGE[32];
  163. switch (emphasis)
  164. {
  165. case Emphasis_None:
  166. return WASABI_API_LNGSTRING_BUF(IDS_NONE,tempGE,32);
  167. case Emphasis_50_15_ms:
  168. return WASABI_API_LNGSTRING_BUF(IDS_50_15_MICROSEC,tempGE,32);
  169. case Emphasis_reserved:
  170. return WASABI_API_LNGSTRING_BUF(IDS_INVALID,tempGE,32);
  171. case Emphasis_CCIT_J_17:
  172. return "CITT j.17";
  173. default:
  174. return WASABI_API_LNGSTRING_BUF(IDS_ERROR,tempGE,32);
  175. }
  176. }
  177. int MPEGFrame::FrameSize()
  178. {
  179. if (layer == Layer1)
  180. {
  181. return (int)floor((48.0f*(float)GetBitrate())/GetSampleRate()) + GetPadding();
  182. }
  183. else if (layer == Layer2 || layer == Layer3)
  184. {
  185. if (mpegVersion == MPEG1)
  186. return (int)floor((144.0f*(float)GetBitrate())/GetSampleRate()) + GetPadding();
  187. else
  188. return (int)floor((72.0f*(float)GetBitrate())/GetSampleRate()) + GetPadding();
  189. }
  190. return 0;
  191. }
  192. const char *MPEGFrame::GetMPEGVersionString()
  193. {
  194. switch(mpegVersion)
  195. {
  196. case MPEG1:
  197. return "MPEG-1";
  198. case MPEG2:
  199. return "MPEG-2";
  200. case MPEG2_5:
  201. return "MPEG-2.5";
  202. default:
  203. static char tempMF[16];
  204. return WASABI_API_LNGSTRING_BUF(IDS_ERROR,tempMF,16);
  205. }
  206. }
  207. const char *MPEGFrame::GetChannelModeString()
  208. {
  209. static char tempGC[32];
  210. switch(channelMode)
  211. {
  212. case Stereo:
  213. return WASABI_API_LNGSTRING_BUF(IDS_STEREO,tempGC,32);
  214. case JointStereo:
  215. return WASABI_API_LNGSTRING_BUF(IDS_JOINT_STEREO,tempGC,32);
  216. case DualChannel:
  217. return WASABI_API_LNGSTRING_BUF(IDS_2_CHANNEL,tempGC,32);
  218. case Mono:
  219. return WASABI_API_LNGSTRING_BUF(IDS_MONO,tempGC,32);
  220. default:
  221. return WASABI_API_LNGSTRING_BUF(IDS_ERROR,tempGC,32);
  222. }
  223. }
  224. int MPEGFrame::GetLayer()
  225. {
  226. switch(layer)
  227. {
  228. case Layer1:
  229. return 1;
  230. case Layer2:
  231. return 2;
  232. case Layer3:
  233. return 3;
  234. default:
  235. return 0;
  236. }
  237. }
  238. int MPEGFrame::GetNumChannels()
  239. {
  240. switch(channelMode)
  241. {
  242. case Stereo:
  243. return 2;
  244. case JointStereo:
  245. return 2;
  246. case DualChannel:
  247. return 2;
  248. case Mono:
  249. return 1;
  250. default:
  251. return 0;
  252. }
  253. }
  254. int ReadLAMEinfo(unsigned char *buffer, LAMEinfo *lameInfo)
  255. {
  256. int flags;
  257. MPEGFrame frame;
  258. frame.ReadBuffer(buffer);
  259. if (!frame.IsSync())
  260. return 0;
  261. lameInfo->h_id = frame.mpegVersion & 1;
  262. lameInfo->samprate = frame.GetSampleRate();
  263. // determine offset of header
  264. if (frame.mpegVersion == MPEGFrame::MPEG1) // MPEG 1
  265. {
  266. if (frame.channelMode == MPEGFrame::Mono)
  267. buffer += (17 + 4);//frame.HeaderSize());
  268. else
  269. buffer += (32 + 4);//frame.HeaderSize());
  270. }
  271. else if (frame.mpegVersion == MPEGFrame::MPEG2) // MPEG 2
  272. {
  273. if (frame.channelMode == MPEGFrame::Mono)
  274. buffer += (9 + 4);//frame.HeaderSize());
  275. else
  276. buffer += (17 + 4);//frame.HeaderSize());
  277. }
  278. else if (frame.mpegVersion == MPEGFrame::MPEG2_5) // MPEG 2
  279. {
  280. if (frame.channelMode == MPEGFrame::Mono)
  281. buffer += (9 + 4);//frame.HeaderSize());
  282. else
  283. buffer += (17 + 4);//frame.HeaderSize());
  284. }
  285. if (!memcmp(buffer, "Info", 4))
  286. lameInfo->cbr=1;
  287. else if (memcmp(buffer, "Xing", 4) && memcmp(buffer, "Lame", 4))
  288. return 0;
  289. buffer += 4; // skip Xing tag
  290. flags = lameInfo->flags = ExtractI4(buffer);
  291. buffer += 4; // skip flags
  292. if (flags & FRAMES_FLAG)
  293. {
  294. lameInfo->frames = ExtractI4(buffer);
  295. buffer += 4; // skip frames
  296. }
  297. if (flags & BYTES_FLAG)
  298. {
  299. lameInfo->bytes = ExtractI4(buffer);
  300. buffer += 4;
  301. }
  302. if (flags & TOC_FLAG)
  303. {
  304. if (lameInfo->toc)
  305. {
  306. for (int i = 0;i < 100;i++)
  307. lameInfo->toc[i] = buffer[i];
  308. }
  309. buffer += 100;
  310. }
  311. lameInfo->vbr_scale = -1;
  312. if (flags & VBR_SCALE_FLAG)
  313. {
  314. lameInfo->vbr_scale = ExtractI4(buffer);
  315. buffer += 4;
  316. }
  317. if (!memcmp(buffer, "LAME", 4))
  318. {
  319. for (int i=0;i<9;i++)
  320. lameInfo->lameTag[i]=*buffer++;
  321. lameInfo->lameTag[9]=0; // null terminate in case tag used all 20 characters
  322. lameInfo->encodingMethod = (*buffer++)&0xF; // we'll grab the VBR method
  323. lameInfo->lowpass = (*buffer++)*100; // lowpass value
  324. lameInfo->peak=*((float *)buffer); // read peak value
  325. buffer+=4; // skip peak value
  326. // read track gain
  327. int16_t gain_word = ExtractI2(buffer);
  328. if ((gain_word & 0xFC00) == 0x2C00)
  329. {
  330. lameInfo->replaygain_track_gain = (float)(gain_word & 0x01FF);
  331. lameInfo->replaygain_track_gain /= 10;
  332. if (gain_word & 0x0200)
  333. lameInfo->replaygain_track_gain = -lameInfo->replaygain_track_gain;
  334. }
  335. buffer+=2;
  336. // read album gain
  337. gain_word = ExtractI2(buffer);
  338. if ((gain_word & 0xFC00) == 0x4C00)
  339. {
  340. lameInfo->replaygain_album_gain = (float)(gain_word & 0x01FF);
  341. lameInfo->replaygain_album_gain /= 10;
  342. if (gain_word & 0x0200)
  343. lameInfo->replaygain_album_gain = -lameInfo->replaygain_album_gain;
  344. }
  345. buffer+=2;
  346. buffer+=1; // skip encoding flags + ATH type
  347. buffer+=1; // skip bitrate
  348. // get the encoder delay and padding, annoyingly as 12 bit values packed into 3 bytes
  349. lameInfo->encoderDelay = ((unsigned short)buffer[0] << 4) | (buffer[1] >> 4);
  350. lameInfo->padding = ((unsigned short)(buffer[1]&0x0F) << 8) | (buffer[2]);
  351. }
  352. return frame.FrameSize();
  353. }