dec_mp3.cpp Source File

Main Page Modules Class Hierarchy Compound List File List Compound Members File Members

# dec_mp3.cpp

    00001 /* MuSE - Multiple Streaming Engine
    00002  * Copyright (C) 2000-2002 Denis Roio aka jaromil <jaromil@dyne.org>
    00003  *
    00004  * This source code is free software; you can redistribute it and/or
    00005  * modify it under the terms of the GNU Public License as published
    00006  * by the Free Software Foundation; either version 2 of the License,
    00007  * or (at your option) any later version.
    00008  *
    00009  * This source code is distributed in the hope that it will be useful,
    00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00012  * Please refer to the GNU Public License for more details.
    00013  *
    00014  * You should have received a copy of the GNU Public License along with
    00015  * this source code; if not, write to:
    00016  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00017  *
    00018  * "$Id: dec_mp3.cpp,v 1.1 2004/02/13 16:58:16 jaromil Exp $"
    00019  *
    00020  */
    00021
    00022 #include <dec_mp3.h>
    00023 #include <jutils.h>
    00024 #include <config.h>
    00025
    00026
    00027 MuseDecMp3::MuseDecMp3() : MuseDec() {
    00028   loader = NULL;
    00029   server = NULL;
    00030   strncpy(name,"Mp3",4);
    00031 }
    00032
    00033 MuseDecMp3::~MuseDecMp3() {
    00034   if(loader) {
    00035     delete loader;
    00036     loader = NULL;
    00037   }
    00038
    00039   if(server) {
    00040     delete server;
    00041     server = NULL;
    00042   }
    00043
    00044 }
    00045
    00046 int MuseDecMp3::load(char *file) {
    00047   func("MuseDecMp3::load(%s)",file);
    00048   int res = 0;
    00049
    00050   loader = Soundinputstream::hopen(file,&res);
    00051   if(loader == NULL) {
    00052     warning("MuseDecMp3::load : i don't see any stream flowing from %s",file);
    00053     //    clean(); // QUAAAAAAA
    00054     //    unlock();
    00055     return(0);
    00056   } // else func("MuseDecMp3->loader %p - OK",loader);
    00057
    00058   server = new Mpegtoraw(loader);
    00059   if(server == NULL) {
    00060     warning("MuseDecMp3::load(%s) - uuops! NULL Mpegtoraw",file);
    00061     delete loader;
    00062     loader = NULL;
    00063     //    clean();
    00064     //    unlock();
    00065     return(0);
    00066   } // else func("MuseDecMp3->server %p - OK",server);
    00067
    00068   server->initialize(file);
    00069
    00070   samplerate = server->getfrequency();
    00071   channels = (server->getmode()<3) ? 2 : 1;
    00072   bitrate = server->getbitrate();
    00073
    00074   /* pcm position */
    00075   framepos = 0;
    00076
    00077   /* check if seekable */
    00078   res = (loader->seekable) ? 1: 2;
    00079   seekable = (loader->seekable) ? true : false;
    00080
    00081   /* get samples in a chunk
    00082      framesize is frames in a chunk (samples / channels) */
    00083   framesize = server->getpcmperframe() * channels;
    00084   //  framesize = samples * channels;
    00085   if(samplerate<=22050) {
    00086     //   if(channels==2) framesize = framesize>>1;
    00087     framesize /=2;
    00088   }
    00089
    00090   //framesize = server->getpcmperframe();
    00091   //  if(samplerate==44100) framesize = framesize<<1;
    00092   /* ?FIX? division needed for 11khz? */
    00093   //  if(channels==1) framesize = framesize;
    00094   //samples = framesize / channels;
    00095
    00096   if(seekable) { /* setup position tracking variables */
    00097     /* total chunks into bitstream (if seekable) */
    00098     frametot = server->gettotalframe();
    00099     /* how much frames make second */
    00100     fps = samplerate / server->getpcmperframe(); // (framesize / channels);
    00101   }
    00102
    00103
    00104   strncpy(_file,file,MAX_PATH_SIZE); /* HACK!
    00105                                         this is normally not needed
    00106                                         see the seek() method for info */
    00107
    00108   /* now the notice is in inchannels.cpp:load()
    00109     notice("Mp3 decoder opened bitstream %uKb/s %uKHz %s %sseekable",
    00110          bitrate,samplerate/1000,
    00111          (channels==1)?"mono":"stereo",
    00112          (seekable)?" ":" non ");
    00113   //  func("for every chunk there are samples[%i] and bytes[%i]",samples,framesize);
    00114   */
    00115   return(res);
    00116 }
    00117
    00118 IN_DATATYPE *MuseDecMp3::get_audio() {
    00119
    00120   if(!server->run(1)) {
    00121     switch(server->geterrorcode()) {
    00122     case SOUND_ERROR_FINISH:
    00123       func("mpeglib: end of stream");
    00124       eos = true;
    00125       return(NULL);
    00126     case SOUND_ERROR_FILEOPENFAIL:
    00127       error("mpeglib: failed opening file (FILEOPENFAIL)");
    00128       err = true;
    00129       return(NULL);
    00130     case SOUND_ERROR_FILEREADFAIL:
    00131       error("mpeglib: failed reading from file (FILEREADFAIL)");
    00132       err = true;
    00133       return(NULL);
    00134     case SOUND_ERROR_UNKNOWNPROXY:
    00135       error("mpeglib: unknown proxy");
    00136       err = true;
    00137       return(NULL);
    00138     case SOUND_ERROR_UNKNOWNHOST:
    00139       error("mpeglib: unknown host");
    00140       err = true;
    00141       return(NULL);
    00142     case SOUND_ERROR_SOCKET:
    00143       error("mpeglib: socket error");
    00144       err = true;
    00145       return(NULL);
    00146     case SOUND_ERROR_CONNECT:
    00147       error("mpeglib: connect error");
    00148       err = true;
    00149       return(NULL);
    00150     case SOUND_ERROR_FDOPEN:
    00151       error("mpeglib: FDOPEN");
    00152       err = true;
    00153       return(NULL);
    00154     case SOUND_ERROR_HTTPFAIL:
    00155       error("mpeglib: http failure");
    00156       err = true;
    00157       return(NULL);
    00158     case SOUND_ERROR_HTTPWRITEFAIL:
    00159       error("mpeglib: http write failed");
    00160       err = true;
    00161       return(NULL);
    00162     case SOUND_ERROR_TOOMANYRELOC:
    00163       error("mpeglib: TOOMANYRELOC");
    00164       err = true;
    00165       return(NULL);
    00166     case SOUND_ERROR_THREADFAIL:
    00167       error("mpeglib: thread failure");
    00168       err = true;
    00169       return(NULL);
    00170     default:
    00171       error("mpeglib: unknown error :(");
    00172       err = true;
    00173       return(NULL);
    00174     }
    00175   }
    00176
    00177   /*
    00178     framesize is the number of frames of data in input
    00179     frames stores how much data we have in
    00180     for mp3 it's fixed coz the framesize never changes
    00181     (maybe with VBR does?) */
    00182   frames = framesize;
    00183   //  samples = frames / channels;
    00184
    00185   if(seekable) {
    00186     framepos = server->getcurrentframe();
    00187   }
    00188
    00189   /* returns a pointer to decoded buffer */
    00190   return((IN_DATATYPE *)server->rawdata);
    00191 }
    00192
    00193 bool MuseDecMp3::seek(float pos) {
    00194   func("MuseDecMp3::seek(%f)",pos);
    00195
    00196   if(pos==0.0) /* HACK! here reload the file
    00197              this is a problem with the mp3 decoder
    00198              we must reload in order to seek to start */
    00199     load(_file);
    00200   else
    00201     server->setframe((int) (frametot*pos));
    00202   /* no error codes out of here :( */
    00203
    00204   return(true);
    00205 }