/* This callback is called each time the sndstream driver needs some more data. It will tell us how much it needs in bytes. */ static void* mpglib_callback(int req_size) { int size, ret; /* Check for file not started or file finished */ if (mp3_fd == 0) return NULL; /* Dump the last PCM packet */ pcm_empty(req_size); /* Loop decoding until we have a full buffer */ while (pcm_count < req_size) { /* Decode frames until we run out of data or space */ printf("decoding previously loaded frame into %08x, %d bytes possible\n", pcm_ptr, PCM_WATER - pcm_count); ret = decodeMP3(&mp, NULL, 0, pcm_ptr, PCM_WATER - pcm_count, &size); printf("ret was %s, size is %d\n", ret == MP3_OK ? "OK" : "ERROR", size); if (ret != MP3_OK) { printf("Refilling the buffer\n"); /* Pull in some more data (and check for EOF) */ if (bs_fill() < 0) { printf("Decode completed\r\n"); goto errorout; } printf("trying decode again...\n"); ret = decodeMP3(&mp, bs_buffer, BS_SIZE, pcm_ptr, PCM_WATER - pcm_count, &size); printf("ret was %s, size is %d\n", ret == MP3_OK ? "OK" : "ERROR", size); } pcm_ptr += size; pcm_count += size; /* frames++; if (!(frames % 64)) { printf("Decoded %d frames \r", frames); }*/ } /* Got it successfully */ return pcm_buffer; errorout: fs_close(mp3_fd); mp3_fd = 0; return NULL; }
DLLEXPORT MPGLIB_ERR MpgLib_DecodeChunk(H_STREAM hStream,PBYTE pInStream,INT nInSize,PBYTE pOutStream,INT nOutSize,PINT pnOutBytes) { /* call decode chunk functions */ if ( (mp.bsize==0) && (nInSize==0) ) return MPGLIB_NEED_MORE; return decodeMP3(&mp,(CHAR*)pInStream,nInSize,(CHAR*)pOutStream,nOutSize,pnOutBytes); }
bool DecodeEngine_Decode(void* pEng,AudioFrame* pDest,void* pData,long nDataLength) { DecodeEngine* pEngine=(DecodeEngine*)pEng; int nDone; int nResult; char* pOut; int nOutSize; int nChannels; if(pDest->getFrameType()==_FRAME_AUDIO_PCM) { pOut=(char*)((PCMFrame*)pDest)->getData(); nOutSize=pDest->getSize(); } else { pOut=(char*)pEngine->aTempBuffer; nOutSize=sizeof(pEngine->aTempBuffer)/sizeof(short); } nResult=decodeMP3(&pEngine->Decoder,(unsigned char*)pData,nDataLength,pOut,nOutSize,&nDone); if(nResult==MP3_OK) { nDone/=sizeof(short); nChannels=pEngine->Decoder.fr.stereo; if(pDest->getFrameType()!=_FRAME_AUDIO_PCM) pDest->putInt16Data((short*)pOut,nDone); else pDest->setLen(nDone); pDest->setFrameFormat((nChannels==2) ? 1 : 0,freqs[pEngine->Decoder.fr.sampling_frequency]); return true; } else if(nResult==MP3_NEED_MORE) { //should never happen otherwise because only whole frames //are passed to HIP and the modified version of HIP we use //here does not buffer data from the beginning for later use //not critical, though pDest->setLen(0); pDest->setFrameFormat(1,44100); return true; } else { //error return false; } }
static int mp3_dqueue(struct ast_filestream *s) { struct mp3_private *p = s->_private; int res=0; if((res = decodeMP3(&p->mp,NULL,0,p->dbuf,MP3_DCACHE,&p->dbuflen)) == MP3_OK) { p->sbuflen -= p->dbuflen; p->dbufoffset = 0; } return res; }
int MP3_Update_OUT(void) { Current_OUT_Pos = 0; if(fatal_mp3_error) return 1; if(decodeMP3(&mp, NULL, 0, buf_out, 8 * 1024, (int*)&Current_OUT_Size) != MP3_OK) return MP3_Update_IN(); return 0; }
int main(int argc,char **argv) { int size; char out[8192]; char swapped; int len,ret; int i; FILE *fp; InitMP3(&mp); fp = fopen( "lala.wav", "w" ); printf( "starting\n" ); while(1) { len = read(0,buf,16384); if(len <= 0) break; ret = decodeMP3(&mp,buf,len,out,8192,&size); printf( "samplerate: %d - channels: %d\n", freqs[mp.fr.sampling_frequency], mp.fr.stereo ); while(ret == MP3_OK) { printf( "written: %d\n", size ); for ( i = 0; i < ( size / 2 ); i++ ) { fputc( out[i*2 + 1], fp ); fputc( out[i*2], fp ); } ret = decodeMP3(&mp,NULL,0,out,8192,&size); } } fclose( fp ); return 0; }
void simuFetchMP3(int ask) { int dstlen; int len; int ret; int loop=1; while((loop)&&(bufplayout_i<ask)) { ret = decodeMP3(&mp,NULL,0,bufmp3,4608,&len); if (ret==MP3_OK) { // printf("freq=%d lsf=%d stereo=%d -> %d\n",freqs[mp.fr.sampling_frequency],mp.fr.lsf,mp.fr.stereo,len); dstlen=getmp3len(freqs[mp.fr.sampling_frequency]); mp3scale((short*)bufmp3,len,bufplayout+bufplayout_i,freqs[mp.fr.sampling_frequency],mp.fr.lsf,mp.fr.stereo,dstlen); bufplayout_i+=dstlen; } else { len=audioPlayFetch(bufplayin+bufplaystart,BUFMP3IN_LENGTH-bufplaystart); len+=bufplaystart; // printf("simuFetchWav get=%d\n",len); if (len) { bufplaystart=0; ret = decodeMP3(&mp,bufplayin,len,bufmp3,4608,&len); if (ret==MP3_OK) { // printf("freq=%d lsf=%d stereo=%d -> %d\n",freqs[mp.fr.sampling_frequency],mp.fr.lsf,mp.fr.stereo,len); dstlen=getmp3len(freqs[mp.fr.sampling_frequency]); mp3scale(bufmp3,len,bufplayout+bufplayout_i,freqs[mp.fr.sampling_frequency],mp.fr.lsf,mp.fr.stereo,dstlen); bufplayout_i+=dstlen; } } else loop=0; } }; }
static int mp3_squeue(struct ast_filestream *s) { struct mp3_private *p = s->_private; int res=0; res = ftell(s->f); p->sbuflen = fread(p->sbuf, 1, MP3_SCACHE, s->f); if(p->sbuflen < 0) { ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", p->sbuflen, strerror(errno)); return -1; } res = decodeMP3(&p->mp,p->sbuf,p->sbuflen,p->dbuf,MP3_DCACHE,&p->dbuflen); if(res != MP3_OK) return -1; p->sbuflen -= p->dbuflen; p->dbufoffset = 0; return 0; }
static int mp3_squeue(struct ast_filestream *s) { struct mp3_private *p = s->_private; int res=0; res = ftell(s->f); p->sbuflen = fread(p->sbuf, 1, MP3_SCACHE, s->f); if (p->sbuflen < MP3_SCACHE) { if (ferror(s->f)) { ast_log(LOG_WARNING, "Error while reading MP3 file: %s\n", strerror(errno)); return -1; } } res = decodeMP3(&p->mp,p->sbuf,p->sbuflen,p->dbuf,MP3_DCACHE,&p->dbuflen); if(res != MP3_OK) return -1; p->sbuflen -= p->dbuflen; p->dbufoffset = 0; return 0; }
int MP3decoder::Decode(BYTE* pbout) { DWORD nTotalSize = 0; int ret; if( m_bfeof ) return 0; do { if( m_dwRestBufSize ){ CopyMemory( pbout, m_pbRestBuf, m_dwRestBufSize ); nTotalSize += m_dwRestBufSize; m_dwRestBufSize = 0; } if( m_outsize ){ if( nTotalSize + m_outsize > BUFFER_SIZE ){ DWORD nRest = BUFFER_SIZE - nTotalSize; CopyMemory( pbout + nTotalSize, out, nRest ); CopyMemory( m_pbRestBuf, out + nRest, m_outsize - nRest); nTotalSize += nRest; m_dwRestBufSize = m_outsize - nRest; m_outsize = 0; break; }else{ CopyMemory( pbout + nTotalSize, out, m_outsize ); nTotalSize += m_outsize; m_outsize = 0; if( nTotalSize == BUFFER_SIZE ) break; } } ret = decodeMP3(&mp,NULL,0,out,8192,&m_outsize); m_pos += m_outsize; if( ret != MP3_OK ){ if( feof( fin ) ) { m_bfeof = true; break; } int nlen = fread(buf, sizeof(BYTE), 16384, fin); ret = decodeMP3(&mp,buf,nlen,out,8192,&m_outsize); m_pos += m_outsize; } if(m_seeked){ m_seeked = false; int nlen = fread(buf, sizeof(BYTE), 16384, fin); if( feof( fin ) ) break; ret = decodeMP3(&mp,buf,nlen,out,8192,&m_outsize); m_pos += m_outsize; nTotalSize = 0; } } while( 1 ); return nTotalSize; }
bool MP3decoder::OpenStream(char* pcfilename,int *isample,int *ichannel,int *ibyte,void * ptSettings, int *bufsizebyte) { unsigned char vbrbuf[VBRHEADERSIZE+36]; m_pos = 0; m_outsize = 0; fin = fopen( pcfilename, "rb" ); if( !fin ) return 0; fseek(fin,0,SEEK_END); m_nInFileSize = ftell(fin); fseek(fin, 0, SEEK_SET); InitMP3(&mp); int nlen = 0; nlen = fread(buf, sizeof(BYTE), 16384, fin); if( nlen < 16384) return 0; int ret = decodeMP3(&mp,buf,nlen,out,8192,&m_outsize); //find good data if( ret != MP3_OK ) return 0; m_pos += m_outsize; /* if( ret != MP3_OK ){ while( ret != MP3_OK ){ ret = decodeMP3(&mp,NULL,0,out,8192,&m_outsize); m_pos += m_outsize; ret = decodeMP3(&mp,NULL,0,out,8192,&m_outsize); m_pos += m_outsize; if( ret == MP3_NEED_MORE ) //tried 16384 bytes, so failed return 0; } }*/ *bufsizebyte = BUFFER_SIZE; *isample = freqs[mp.fr.sampling_frequency]; *ibyte = 2; *ichannel = mp.fr.stereo; memcpy(vbrbuf, mp.tail->pnt + mp.ndatabegin, VBRHEADERSIZE+36); if (GetVbrTag(&vbrtag,(BYTE*)vbrbuf)) { if( vbrtag.frames < 1 || vbrtag.bytes < 1 ) return 0; int cur_bitrate = (int)(vbrtag.bytes*8/(vbrtag.frames*576.0*(mp.fr.lsf?1:2)/freqs[mp.fr.sampling_frequency])); m_length = vbrtag.frames*576.0*(mp.fr.lsf?1:2)/freqs[mp.fr.sampling_frequency]*1000; m_nbytes = vbrtag.bytes; m_hasVbrtag = 1; } else { double bpf = 0, tpf = 0; bpf = compute_bpf(&mp.fr); tpf = compute_tpf(&mp.fr); m_length = (DWORD)((double)(m_nInFileSize)/bpf*tpf)*1000; m_hasVbrtag = 0; } fseek(fin,16384,SEEK_SET); m_dwRestBufSize = 0; m_seeked = false; m_bfeof = false; return 1; }
/* Open an MPEG stream and prepare for decode */ static int mpglib_init(const char *fn) { uint32 fd; int size; /* Open the file */ mp3_fd = fd = fs_open(fn, O_RDONLY); if (fd < 0) { printf("Can't open input file %s\r\n", fn); printf("getwd() returns '%s'\r\n", fs_getwd()); return -1; } if (fn != mp3_last_fn) { if (fn[0] != '/') { strcpy(mp3_last_fn, fs_getwd()); strcat(mp3_last_fn, "/"); strcat(mp3_last_fn, fn); } else { strcpy(mp3_last_fn, fn); } } /* Allocate buffers */ if (bs_buffer == NULL) bs_buffer = malloc(BS_SIZE); bs_ptr = bs_buffer; bs_count = 0; if (pcm_buffer == NULL) pcm_buffer = malloc(PCM_SIZE); pcm_ptr = pcm_buffer; pcm_count = pcm_discard = 0; /* Fill bitstream buffer */ if (bs_fill() < 0) { printf("Can't read file header\r\n"); goto errorout; } /* Are we looking at a RIFF file? (stupid Windows encoders) */ if (bs_ptr[0] == 'R' && bs_ptr[1] == 'I' && bs_ptr[2] == 'F' && bs_ptr[3] == 'F') { /* Found a RIFF header, scan through it until we find the data section */ printf("Skipping stupid RIFF header\r\n"); while (bs_ptr[0] != 'd' || bs_ptr[1] != 'a' || bs_ptr[2] != 't' || bs_ptr[3] != 'a') { bs_ptr++; if (bs_ptr >= (bs_buffer + BS_SIZE)) { printf("Indeterminately long RIFF header\r\n"); goto errorout; } } /* Skip 'data' and length */ bs_ptr += 8; bs_count -= (bs_ptr - bs_buffer); printf("Final index is %d\r\n", (bs_ptr - bs_buffer)); } if (((uint8)bs_ptr[0] != 0xff) && (!((uint8)bs_ptr[1] & 0xe0))) { printf("Definitely not an MPEG file\r\n"); goto errorout; } /* Initialize MPEG engines */ InitMP3(&mp); /* Decode the first frame */ printf("decoding first frame:\n"); decodeMP3(&mp, bs_buffer, BS_SIZE, pcm_ptr, PCM_WATER - pcm_count, &size); printf("decoded size was %d\n", size); pcm_ptr += size; pcm_count += size; printf("mpglib initialized successfully\r\n"); return 0; errorout: printf("Exiting on error\r\n"); if (bs_buffer) { free(bs_buffer); bs_buffer = NULL; } if (pcm_buffer) { free(pcm_buffer); pcm_buffer = NULL; } fs_close(fd); mp3_fd = 0; return -1; }
void Preload_MP3_Synchronous(FILE** filePtr, int track) { if(filePtr && track >= 0 && track < 100) { if(!*filePtr && Tracks[track].Type == TYPE_MP3) { char str [1024], msg [256]; int prevTrack = Track_Played; FILE* file = NULL; SetCurrentDirectory(Gens_Path); _mkdir(PRELOADED_MP3_DIRECTORY); sprintf(str, PRELOADED_MP3_DIRECTORY PRELOADED_MP3_FILENAME, track+1); #ifdef _WIN32 sprintf(msg, "Loading track %02d MP3", track+1); Put_Info_NonImmediate(msg, 100); #else sprintf(msg, "Preloading track %02d MP3", track+1); Put_Info(msg, 100); #endif if(Preload_MP3_Synchronous_Cancel) return; //Tracks[track].F_decoded = fopen(str, "wb+"); if(preloaded_tracks[track] == 3) file = fopen(str, "r+b"); else file = fopen(str, "w+b"); if(Preload_MP3_Synchronous_Cancel && track != Preload_MP3_Synchronous_Cancel_Exception) { if(file) fclose(file); return; } preloaded_tracks[track] = 3; if(file) { // decode mp3 to the temporary file static const int inSize = 588*4, outSize = 8192; char temp_in_buf[inSize], temp_out_buf[outSize]; int inRead = 0, outRead = 0; int ok = MP3_OK; mpstr temp_mp; InitMP3(&temp_mp); int inStartPos = MP3_Find_Frame(Tracks[track].F, 0); fseek(file, 0, SEEK_END); int outStartPos = ftell(file); int outPos = 0; fseek(Tracks[track].F, inStartPos, SEEK_SET); int iter = 0; while(ok == MP3_OK && !(Preload_MP3_Synchronous_Cancel && track != Preload_MP3_Synchronous_Cancel_Exception)) { inRead = fread(temp_in_buf, 1, inSize, Tracks[track].F); ok = decodeMP3(&temp_mp, temp_in_buf, inRead, temp_out_buf, outSize, (int*)&outRead); if(outPos >= outStartPos) fwrite(temp_out_buf, outRead, 1, file); outPos += outRead; ++iter; #ifdef _WIN32 // even with "lowest priority" set on this thread, on win32, // it still prevents other threads from doing processing for long enough // to cause stuttering problems, even with multiple CPU cores present, // so voluntarily give up control of the thread by sleeping every few decoding iterations if(!Waiting_For_Preload_MP3_Synchronous) if(iter % 16 == 0) Sleep(10); else Sleep(0); #endif } if((Preload_MP3_Synchronous_Cancel && track != Preload_MP3_Synchronous_Cancel_Exception) || ferror(file)) // if we got some error (out of disk space?) give up on pre-loading the MP3 { fclose(file); file = NULL; } } else { // couldn't open, maybe another instance of Gens has it open? if so use that file = fopen(str, "rb"); } *filePtr = file; } } if(!(Preload_MP3_Synchronous_Cancel && track != Preload_MP3_Synchronous_Cancel_Exception)) preloaded_tracks[track] = (filePtr && *filePtr) ? 1 : 0; }
static Uint32 MPGLIB_read(Sound_Sample *sample) { Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; mpglib_t *mpg = ((mpglib_t *) internal->decoder_private); Uint32 bw = 0; int rc; while (bw < internal->buffer_size) { if (mpg->outleft > 0) { size_t cpysize = internal->buffer_size - bw; if (cpysize > mpg->outleft) cpysize = mpg->outleft; memcpy(((Uint8 *) internal->buffer) + bw, mpg->outbuf + mpg->outpos, cpysize); bw += cpysize; mpg->outpos += cpysize; mpg->outleft -= cpysize; continue; } /* if */ /* need to decode more from the MP3 stream... */ mpg->outpos = 0; rc = decodeMP3(&mpg->mp, NULL, 0, mpg->outbuf, sizeof (mpg->outbuf), &mpg->outleft); if (rc == MP3_ERR) { sample->flags |= SOUND_SAMPLEFLAG_ERROR; return(bw); } /* if */ else if (rc == MP3_NEED_MORE) { rc = SDL_RWread(internal->rw, mpg->inbuf, 1, sizeof (mpg->inbuf)); if (rc == -1) { sample->flags |= SOUND_SAMPLEFLAG_ERROR; return(bw); } /* if */ else if (rc == 0) { sample->flags |= SOUND_SAMPLEFLAG_EOF; return(bw); } /* else if */ /* make sure there isn't an ID3 tag. */ /* * !!! FIXME: This can fail under the following circumstances: * First, if there's the sequence "TAG" 128 bytes from the end * of a read that isn't the EOF. This is unlikely. * Second, if the TAG sequence is split between two reads (ie, * the last byte of a read is 'T', and the next read is the * final 127 bytes of the stream, being the rest of the ID3 tag). * While this is more likely, it's still not very likely at all. * Still, something SHOULD be done about this. * ID3v2 tags are more complex, too, not to mention LYRICS tags, * etc, which aren't handled, either. Hey, this IS meant to be * a lightweight decoder. Use SMPEG if you need an all-purpose * decoder. mpglib really assumes you control all your assets. */ if (rc >= 128) { Uint8 *ptr = &mpg->inbuf[rc - 128]; if ((ptr[0] == 'T') && (ptr[1] == 'A') && (ptr[2] == 'G')) rc -= 128; /* disregard it. */ } /* if */ rc = decodeMP3(&mpg->mp, mpg->inbuf, rc, mpg->outbuf, sizeof (mpg->outbuf), &mpg->outleft); if (rc == MP3_ERR) { sample->flags |= SOUND_SAMPLEFLAG_ERROR; return(bw); } /* if */ } /* else if */ } /* while */ return(bw); } /* MPGLIB_read */
static int MPGLIB_open(Sound_Sample *sample, const char *ext) { Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; mpglib_t *mpg = NULL; int rc; /* * If I understand things correctly, MP3 files don't really have any * magic header we can check for. The MP3 player is expected to just * pick the first thing that looks like a valid frame and start * playing from there. * * So here's what we do: If the caller insists that this is really * MP3 we'll take his word for it. Otherwise, use the same test as * SDL_mixer does and check if the stream starts with something that * looks like a frame. * * A frame begins with 11 bits of frame sync (all bits must be set), * followed by a two-bit MPEG Audio version ID: * * 00 - MPEG Version 2.5 (later extension of MPEG 2) * 01 - reserved * 10 - MPEG Version 2 (ISO/IEC 13818-3) * 11 - MPEG Version 1 (ISO/IEC 11172-3) * * Apparently we don't handle MPEG Version 2.5. */ if (__Sound_strcasecmp(ext, "MP3") != 0) { Uint8 mp3_magic[2]; if (SDL_RWread(internal->rw, mp3_magic, sizeof (mp3_magic), 1) != 1) BAIL_MACRO("MPGLIB: Could not read MP3 magic.", 0); if (mp3_magic[0] != 0xFF || (mp3_magic[1] & 0xF0) != 0xF0) BAIL_MACRO("MPGLIB: Not an MP3 stream.", 0); /* If the seek fails, we'll probably miss a frame, but oh well. */ SDL_RWseek(internal->rw, -sizeof (mp3_magic), SEEK_CUR); } /* if */ mpg = (mpglib_t *) malloc(sizeof (mpglib_t)); BAIL_IF_MACRO(mpg == NULL, ERR_OUT_OF_MEMORY, 0); memset(mpg, '\0', sizeof (mpglib_t)); InitMP3(&mpg->mp); rc = SDL_RWread(internal->rw, mpg->inbuf, 1, sizeof (mpg->inbuf)); if (rc <= 0) { free(mpg); BAIL_MACRO("MPGLIB: Failed to read any data at all", 0); } /* if */ if (decodeMP3(&mpg->mp, mpg->inbuf, rc, mpg->outbuf, sizeof (mpg->outbuf), &mpg->outleft) == MP3_ERR) { free(mpg); BAIL_MACRO("MPGLIB: Not an MP3 stream?", 0); } /* if */ SNDDBG(("MPGLIB: Accepting data stream.\n")); internal->decoder_private = mpg; sample->actual.rate = mpglib_freqs[mpg->mp.fr.sampling_frequency]; sample->actual.channels = mpg->mp.fr.stereo; sample->actual.format = AUDIO_S16SYS; sample->flags = SOUND_SAMPLEFLAG_NONE; return(1); /* we'll handle this data. */ } /* MPGLIB_open */
status_t mp3Decoder::DecodeNextChunk() { const void *chunkBuffer; size_t chunkSize; media_header mh; int outsize; int result; status_t err; // decode residual data that is still in the decoder first result = decodeMP3(&fMpgLibPrivate, 0, 0, (char *)fDecodeBuffer, DECODE_BUFFER_SIZE, &outsize); if (result == MP3_OK) { fResidualBuffer = fDecodeBuffer; fResidualBytes = outsize; return B_OK; } // get another chunk and push it to the decoder err = GetNextChunk(&chunkBuffer, &chunkSize, &mh); if (err != B_OK) return err; fStartTime = mh.start_time; // TRACE("mp3Decoder: fStartTime reset to %.6f\n", fStartTime / 1000000.0); // resync after a seek if (fNeedSync) { TRACE("mp3Decoder::DecodeNextChunk: Syncing...\n"); if (chunkSize < 4) { TRACE("mp3Decoder::DecodeNextChunk: Sync failed, frame too small\n"); return B_ERROR; } int len = GetFrameLength(chunkBuffer); TRACE("mp3Decoder::DecodeNextChunk: chunkSize %ld, first frame length %d\n", chunkSize, len); // len == -1 when not at frame start // len == chunkSize for mp3 reader (delivers single frames) if (len < (int)chunkSize) { // FIXME: join a few chunks to create a larger (2k) buffer, and use: // while (chunkSize > 100) { // if (IsValidStream((uint8 *)chunkBuffer, chunkSize)) while (chunkSize >= 4) { if (GetFrameLength(chunkBuffer) > 0) break; chunkBuffer = (uint8 *)chunkBuffer + 1; chunkSize--; } // if (chunkSize <= 100) { if (chunkSize == 3) { TRACE("mp3Decoder::DecodeNextChunk: Sync failed\n"); return B_ERROR; } TRACE("mp3Decoder::DecodeNextChunk: new chunkSize %ld, first frame length %d\n", chunkSize, GetFrameLength(chunkBuffer)); } fNeedSync = false; } result = decodeMP3(&fMpgLibPrivate, (char *)chunkBuffer, chunkSize, (char *)fDecodeBuffer, DECODE_BUFFER_SIZE, &outsize); if (result == MP3_NEED_MORE) { TRACE("mp3Decoder::DecodeNextChunk: decodeMP3 returned MP3_NEED_MORE\n"); fResidualBuffer = NULL; fResidualBytes = 0; return B_OK; } else if (result != MP3_OK) { TRACE("mp3Decoder::DecodeNextChunk: decodeMP3 returned error %d\n", result); return B_ERROR; // fNeedSync = true; // fResidualBuffer = NULL; // fResidualBytes = 0; // return B_OK; } //printf("mp3Decoder::Decode: decoded %d bytes into %d bytes\n",chunkSize, outsize); fResidualBuffer = fDecodeBuffer; fResidualBytes = outsize; return B_OK; }
PDGL_Sample *PDGL_Sound_LoadMP3(char *name) { VFILE *fd; PDGL_Sample *tmp; struct mpstr mp; int i, j; byte *buf, *s, *ibuf, *obuf; int chan, rate, bits, bitrate, lty; int len, ret, size, bufsize, ofs; kprint("PDGL_Sound_LoadMP3: Loading sample '%s'\n", name); fd=vffopen(name, "rb"); if(!fd) { kprint("PDGL_Sound_LoadMP3: Failed open sample '%s'\n", name); return(NULL); } InitMP3(&mp); buf=malloc(10<<20); s=buf; ibuf=kalloc(16384); obuf=kalloc(16384); len=vfread(ibuf, 1, 16384, fd); ofs=statMP3(ibuf, &rate, &chan, &bitrate, <y); bits=16; kprint("PDGL_Sound_LoadMP3: %d Hz, %d chan, %d bps, layer %d, ofs %d\n", rate, chan, bitrate, lty, ofs); vfseek(fd, 0, 2); size=vftell(fd); len=(size+((bitrate/8)-1))/(bitrate/8); bufsize=len*rate*chan*4; //2x est stream len kprint("PDGL_Sound_LoadMP3: aprox %d seconds, buf %d bytes\n", len, bufsize); vfseek(fd, ofs, 0); buf=malloc(bufsize); s=buf; while(!vfeof(fd)) { len=vfread(ibuf, 1, 16384, fd); if(len<=0)break; ret = decodeMP3(&mp,ibuf,len,obuf,16384,&size); while(ret == MP3_OK) { memcpy(s, obuf, size); s+=size; ret = decodeMP3(&mp,NULL,0,obuf,16384,&size); } if((s-buf)>((bufsize*2)/3)) { kprint("PDGL_Sound_LoadMP3: overflow\n"); break; } } len=s-buf; kprint("PDGL_Sound_LoadMP3: decoded %f seconds\n", (float)len/(rate*chan*2)); tmp=PDGL_Sound_SampleFromBuf(name, buf, chan, rate, bits, len); kfree(ibuf); kfree(obuf); free(buf); return(tmp); }
int MP3_Update_IN(void) { char buf_in[8 * 1024]; int size_read; if (Tracks[Track_Played].F == NULL) return -1; fseek(Tracks[Track_Played].F, Current_IN_Pos, SEEK_SET); size_read = fread(buf_in, 1, 8 * 1024, Tracks[Track_Played].F); Current_IN_Pos += size_read; if (size_read <= 0 || fatal_mp3_error) { int rv; if(!allowContinueToNextTrack) return 6; // go to the next track SCD.Cur_Track = ++Track_Played + 1; // because Cur_Track may or may not have already been incremented, and it's 1-based whereas Track_Played is 0-based played_tracks_linear[SCD.Cur_Track - SCD.TOC.First_Track] = 1; rv = FILE_Play_CD_LBA(1); if(rv) return rv; ResetMP3_Gens(&mp); if (Tracks[Track_Played].Type == TYPE_WAV) { // WAV_Play(); return 4; } else if (Tracks[Track_Played].Type != TYPE_MP3) { return 5; } Current_IN_Pos = MP3_Find_Frame(Tracks[Track_Played].F, 0); fseek(Tracks[Track_Played].F, Current_IN_Pos, SEEK_SET); size_read = fread(buf_in, 1, 8 * 1024, Tracks[Track_Played].F); Current_IN_Pos += size_read; } if(fatal_mp3_error) return 1; if (decodeMP3(&mp, buf_in, size_read, buf_out, 8 * 1024, (int*)&Current_OUT_Size) != MP3_OK) { fseek(Tracks[Track_Played].F, Current_IN_Pos, SEEK_SET); size_read = fread(buf_in, 1, 8 * 1024, Tracks[Track_Played].F); Current_IN_Pos += size_read; if (decodeMP3(&mp, buf_in, size_read, buf_out, 8 * 1024, (int*)&Current_OUT_Size) != MP3_OK) { fatal_mp3_error = 1; return 1; } } return 0; }
int main(int argc, char **argv){ char *bufout; char *bufin; path_id path,devpath; error_code error; u_int32 bufsize_out = OUT_BUF_SIZE; u_int32 bufsize_in = IN_BUF_SIZE; u_int32 count; int inlen,outlen; char *compbuf=NULL; int compbuflen=0,compbufpos=0; int status=MP3_OK; int i; struct mpstr mp; int iflag=0; if (argc != 3) { printf("Play MP3 file\n"); printf("Usage: mpgplay <filename><device>\n"); exit(1); } /* set up signal handler */ intercept (sighand); /* Initialize the MP3 decoder */ InitMP3(&mp); if ((error = _os_open(argv[1], FAM_READ, &path)) != SUCCESS) { return error; } /* Prepare the Sound device */ if ((error = _os_open(argv[2], FAM_WRITE, &devpath)) != SUCCESS) { return error; } if ((error = _os_srqmem (&bufsize_in, (void**)&bufin, 0)) != SUCCESS) { return error; } if ((error = _os_srqmem (&bufsize_out, (void**)&bufout, 0)) != SUCCESS) { return error; } sigval = SMAP_DONE_SIG; /* Sound is free */ #if defined(SHOW_TIME_INFO) time (&initial_time); #endif while(status != MP3_ERR){ count = IN_BUF_SIZE; /* read the data */ if ((error = _os_read(path, bufin, &count)) != SUCCESS){ if (error == EOS_EOF) break; /* done */ else return error; } inlen = count; /* Initialize buffer */ outlen = compbufpos = compbuflen = 0; status = decodeMP3(&mp,bufin,inlen,bufout,OUT_BUF_SIZE,&outlen); if (!iflag){ printf("Playing %s [%s - %dkbs]\n", argv[1], mp.fr.stereo?"Stereo":"Mono", frequencies[mp.fr.sampling_frequency]); #if defined(SHOW_FRAME) printf("FRAME: stereo %d jsbound %d single %d lsf %d\n", mp.fr.stereo, mp.fr.jsbound, mp.fr.single, mp.fr.lsf); printf("mpeg25 %d header_change %d lay %d error_protection %d\n", mp.fr.mpeg25, mp.fr.header_change, mp.fr.lay, mp.fr.error_protection); printf("bitrate_index %d sampling_frequency %d padding %d extension %d\n", mp.fr.bitrate_index, mp.fr.sampling_frequency, mp.fr.padding, mp.fr.extension); printf("mode %d mode_ext %d copyright %d original %d\n", mp.fr.mode, mp.fr.mode_ext, mp.fr.copyright, mp.fr.original); printf("emphasis %d framesize %d\n", mp.fr.emphasis, mp.fr.framesize); #endif iflag=1; } while(status == MP3_OK){ /* Check buffer size */ if ((compbufpos + outlen) > compbuflen || compbuf == NULL) { compbuflen = compbufpos+outlen; compbuf = (char *) realloc(compbuf,compbuflen); } memcpy(compbuf+compbufpos,bufout,outlen); compbufpos+=outlen; status = decodeMP3(&mp,NULL,0,bufout,OUT_BUF_SIZE,&outlen); } if (compbufpos) { int blks = compbufpos / SND_BLK_SIZE; int residual = compbufpos - (blks*SND_BLK_SIZE); #if defined(SHOW_TIME_INFO) { time (¤t_time); ts_time_decompose ( (unsigned long)difftime (current_time, initial_time)); total_blks += (blks+1); } #endif /* Wait for buffer slot to empty */ sigmask(1); if (sigval != SMAP_DONE_SIG){ tsleep(0); } else sigmask(-1); sigval = 0; if (compbufpos > sound_buffer_size) { sound_buffer = (u_char *) realloc(sound_buffer,compbufpos); } sound_buffer_size = compbufpos; memcpy(sound_buffer,compbuf,sound_buffer_size); /* * Fill up the sound maps */ for(i=0;i<blks;i++) { smap[i].num_channels = mp.fr.stereo; smap[i].sample_rate = frequencies[mp.fr.sampling_frequency]; smap[i].coding_method = CODING_METHOD; smap[i].sample_size = SAMPLE_SIZE; smap[i].cur_offset = 0; smap[i].loop_start = 0; smap[i].loop_count = 1; smap[i].loop_counter = 0; smap[i].next = &smap[i+1]; smap[i].trig_mask = 0; smap[i].trig_signal = 0; /* get the size of the data in this read */ smap[i].buf_size = smap[i].loop_end = SND_BLK_SIZE; smap[i].buf = &sound_buffer[i*SND_BLK_SIZE]; } /* If we do not have residual then back up to last sound map 1st */ if (residual==0) i--; /* Last block in chain */ smap[i].num_channels = mp.fr.stereo; smap[i].sample_rate = frequencies[mp.fr.sampling_frequency]; smap[i].coding_method = CODING_METHOD; smap[i].sample_size = SAMPLE_SIZE; smap[i].cur_offset = 0; smap[i].loop_start = 0; smap[i].loop_count = 1; smap[i].loop_counter = 0; smap[i].next = NULL; smap[i].trig_mask = SND_TRIG_READY; smap[i].trig_signal = SMAP_DONE_SIG; /* get the size of the data in this read */ smap[i].buf_size = smap[i].loop_end = residual?residual:SND_BLK_SIZE; smap[i].buf = &sound_buffer[i*SND_BLK_SIZE]; if ((error = _os_ss_snd_play(devpath, &smap[0], SND_NOBLOCK )) != SUCCESS) { return error; } compbufpos = 0; } } #if defined(SHOW_TIME_INFO) printf("\n"); #endif /* Wait for buffer slot to empty */ sigmask(1); if (sigval != SMAP_DONE_SIG){ tsleep(0); } else sigmask(-1); /* Exit the MP3 decoder */ ExitMP3(&mp); _os_srtmem(bufsize_in, (void *)bufin); _os_srtmem(bufsize_out, (void *)bufout); }