#ifndef MP3_H #define MP3_H /* * @(#)MP3.h * * This file is part of webCDwriter - Network CD Writing. * * Copyright (C) 2002 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. */ #include "File.h" #include "FileInputStream.h" /** * A class to handle MP3 files. * * @version 20021017 * @author Jörg P. M. Haeger */ class MP3 { private: int format; int channels; long frequency; long bytesPerSecond; int bytesPerSample; long dataLength; long firstHeaderStart; int MPEGVersion; int layer; int bitrate; public: MP3(File &file) { static const int kbps[2][3][15] = { { {1, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, {1, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, {1, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320} }, { {1, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, {1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, {1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} } }; FileInputStream inStream = new FileInputStream(file); firstHeaderStart = 0; while (true) { int b = inStream.read(); if (b == -1) throw new Exception("is not a MP3"); if (b != 0xFF) { firstHeaderStart++; continue; } b = inStream.read(); if (b < 0xF0) { firstHeaderStart += 2; continue; } switch (b & 0x08) { case 0x00: MPEGVersion = 2; break; case 0x08: MPEGVersion = 1; break; } switch (b & 0x06) { case 0x00: layer = 0; break; case 0x02: layer = 3; break; case 0x04: layer = 2; break; case 0x06: layer = 1; break; } b = inStream.read(); if (b >= 0xF0) { firstHeaderStart += 3; continue; } bitrate = kbps[MPEGVersion - 1][layer - 1][(b & 0xF0) >> 4]; if (MPEGVersion == 1) switch (b & 0x0C) { case 0x00: frequency = 44100; break; case 0x04: frequency = 48000; break; case 0x08: frequency = 32000; break; case 0x0C: frequency = -1; break; } else if (MPEGVersion == 2) switch (b & 0x0C) { case 0x00: frequency = 22050; break; case 0x04: frequency = 24000; break; case 0x08: frequency = 16000; break; case 0x0C: frequency = -1; break; } b = inStream.read(); switch (b & 0xC0) { case 0x00: channels = 2; break; case 0x40: channels = 2; break; case 0x80: channels = 2; break; case 0xC0: channels = 1; break; } break; } dataLength = file.getSize(); bytesPerSecond = 1000 * bitrate / 8; } long getSeconds() { if (bytesPerSecond > 0) return dataLength / bytesPerSecond; else return 0; } }; #endif