00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MP3FileSource.hh"
00022 #include "MP3StreamState.hh"
00023 #include "InputFile.hh"
00024
00026
00027 MP3FileSource::MP3FileSource(UsageEnvironment& env, FILE* fid)
00028 : FramedFileSource(env, fid),
00029 fStreamState(new MP3StreamState(env)) {
00030 }
00031
00032 MP3FileSource::~MP3FileSource() {
00033 delete fStreamState;
00034 }
00035
00036 char const* MP3FileSource::MIMEtype() const {
00037 return "audio/MPEG";
00038 }
00039
00040 MP3FileSource* MP3FileSource::createNew(UsageEnvironment& env, char const* fileName) {
00041 MP3FileSource* newSource = NULL;
00042
00043 do {
00044 FILE* fid;
00045
00046 fid = OpenInputFile(env, fileName);
00047 if (fid == NULL) break;
00048
00049 newSource = new MP3FileSource(env, fid);
00050 if (newSource == NULL) break;
00051
00052 unsigned fileSize = (unsigned)GetFileSize(fileName, fid);
00053 newSource->assignStream(fid, fileSize);
00054 if (!newSource->initializeStream()) break;
00055
00056 return newSource;
00057 } while (0);
00058
00059 Medium::close(newSource);
00060 return NULL;
00061 }
00062
00063 float MP3FileSource::filePlayTime() const {
00064 return fStreamState->filePlayTime();
00065 }
00066
00067 void MP3FileSource::setPresentationTimeScale(unsigned scale) {
00068 fStreamState->setPresentationTimeScale(scale);
00069 }
00070
00071 void MP3FileSource::seekWithinFile(float seekNPT) {
00072 fStreamState->seekWithinFile(seekNPT);
00073 }
00074
00075 void MP3FileSource::getAttributes() const {
00076 char buffer[200];
00077 fStreamState->getAttributes(buffer, sizeof buffer);
00078 envir().setResultMsg(buffer);
00079 }
00080
00081 void MP3FileSource::doGetNextFrame() {
00082 if (!doGetNextFrame1()) {
00083 handleClosure(this);
00084 return;
00085 }
00086
00087
00088 #if defined(__WIN32__) || defined(_WIN32)
00089
00090
00091
00092
00093
00094
00095 afterGetting(this);
00096 #else
00097 nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
00098 (TaskFunc*)afterGetting, this);
00099 #endif
00100 }
00101
00102 Boolean MP3FileSource::doGetNextFrame1() {
00103 if (!fHaveJustInitialized) {
00104 if (fStreamState->findNextHeader(fPresentationTime) == 0) return False;
00105 } else {
00106 fPresentationTime = fFirstFramePresentationTime;
00107 fHaveJustInitialized = False;
00108 }
00109
00110 if (!fStreamState->readFrame(fTo, fMaxSize, fFrameSize, fDurationInMicroseconds)) {
00111 char tmp[200];
00112 sprintf(tmp,
00113 "Insufficient buffer size %d for reading MPEG audio frame (needed %d)\n",
00114 fMaxSize, fFrameSize);
00115 envir().setResultMsg(tmp);
00116 fFrameSize = fMaxSize;
00117 return False;
00118 }
00119
00120 return True;
00121 }
00122
00123 void MP3FileSource::assignStream(FILE* fid, unsigned fileSize) {
00124 fStreamState->assignStream(fid, fileSize);
00125 }
00126
00127
00128 Boolean MP3FileSource::initializeStream() {
00129
00130 if (fStreamState->findNextHeader(fFirstFramePresentationTime) == 0) {
00131 envir().setResultMsg("not an MPEG audio file");
00132 return False;
00133 }
00134
00135 fStreamState->checkForXingHeader();
00136
00137 fHaveJustInitialized = True;
00138
00139
00140 envir().setResultMsg(name());
00141 return True;
00142 }