int main(int argc,char **argv) { int size; char out[8192]; int len,ret; int f, fo; f = open(argv[1], O_RDONLY); fo = open(argv[2], O_CREAT | O_WRONLY); printf("f %d fo %d\n", f, fo); InitMP3(&mp); while(1) { len = read(f,buf,16384); if(len <= 0) break; ret = decodeMP3(&mp,buf,len,out,8192,&size); while(ret == MP3_OK) { write(fo,out,size); ret = decodeMP3(&mp,NULL,0,out,8192,&size); } } close(f); close(fo); return 0; }
int MP3_Init(void) { InitMP3(&mp); MP3_Reset(); return 0; }
DLLEXPORT MPGLIB_ERR MpgLib_OpenStream(H_STREAM phStream) { /* clear mp structure */ memset(&mp,0x00,sizeof(mp)); /* set stream parameter, not used right now */ phStream=1; /* call decoder init function */ return InitMP3(&mp); }
void* DecodeEngine_Create() { DecodeEngine* pEngine=new DecodeEngine; if(!InitMP3(&pEngine->Decoder)) { delete pEngine; pEngine=(DecodeEngine*)0; } return pEngine; }
int hip_decode_init(hip_t hip) { if (hip == NULL) { return sizeof(hip_global_flags); } InitMP3(hip); ((PMPSTR)hip)->signature = HIP_SIGNATURE; return 0; }
static int MPGLIB_rewind(Sound_Sample *sample) { Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; mpglib_t *mpg = ((mpglib_t *) internal->decoder_private); BAIL_IF_MACRO(SDL_RWseek(internal->rw, 0, SEEK_SET) != 0, ERR_IO_ERROR, 0); /* this is just resetting some fields in a structure; it's very fast. */ ExitMP3(&mpg->mp); InitMP3(&mpg->mp); mpg->outpos = mpg->outleft = 0; return(1); } /* MPGLIB_rewind */
status_t mp3Decoder::Decode(void *buffer, int64 *frameCount, media_header *mediaHeader, media_decode_info *info /* = 0 */) { status_t last_err = B_LAST_BUFFER_ERROR; uint8 * out_buffer = static_cast<uint8 *>(buffer); int32 out_bytes_needed = fOutputBufferSize; int32 out_bytes = 0; fStartTime = (bigtime_t)(fSampleNo *1000000LL / fFrameRate); mediaHeader->start_time = fStartTime; while (out_bytes_needed > 0) { if (fNeedSync) { TRACE("mp3Decoder::Decode: syncing...\n"); ExitMP3(&fMpgLibPrivate); InitMP3(&fMpgLibPrivate); fDecodingError = false; fResidualBytes = 0; // fNeedSync is reset in DecodeNextChunk } if (fDecodingError) return B_ERROR; if (fResidualBytes) { int32 bytes = min_c(fResidualBytes, out_bytes_needed); memcpy(out_buffer, fResidualBuffer, bytes); fResidualBuffer += bytes; fResidualBytes -= bytes; out_buffer += bytes; out_bytes += bytes; out_bytes_needed -= bytes; continue; } last_err = DecodeNextChunk(); if (last_err != B_OK) { fDecodingError = true; break; } } *frameCount = out_bytes / fFrameSize; fSampleNo += *frameCount; TRACE("framecount %Ld, time %.6f\n", *frameCount, mediaHeader->start_time / 1000000.0); return (out_bytes > 0) ? B_OK : last_err; }
mp3Decoder::mp3Decoder() { InitMP3(&fMpgLibPrivate); fResidualBytes = 0; fResidualBuffer = 0; fDecodeBuffer = new uint8 [DECODE_BUFFER_SIZE]; fStartTime = 0; fFrameSize = 0; fFrameRate = 0; fBitRate = 0; fChannelCount = 0; fOutputBufferSize = 0; fNeedSync = true; // some files start with garbage fDecodingError = false; fSampleNo = 0; }
/*********************************************************************** * MPEG3_StreamOpen * */ static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi) { AcmMpeg3Data* aad; assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC)); if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF || MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data)); if (aad == 0) return MMSYSERR_NOMEM; adsi->dwDriver = (DWORD)aad; if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) { goto theEnd; } else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 && adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) { /* resampling or mono <=> stereo not available * MPEG3 algo only define 16 bit per sample output */ if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec || adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels || adsi->pwfxDst->wBitsPerSample != 16) goto theEnd; aad->convert = mp3_horse; InitMP3(&aad->mp); } /* no encoding yet else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3) */ else goto theEnd; MPEG3_Reset(adsi, aad); return MMSYSERR_NOERROR; theEnd: HeapFree(GetProcessHeap(), 0, aad); adsi->dwDriver = 0L; return MMSYSERR_NOTSUPPORTED; }
void DecodeEngine_Flush(void* pEng) { DecodeEngine* pEngine=(DecodeEngine*)pEng; //complete reinit ExitMP3(&pEngine->Decoder); InitMP3(&pEngine->Decoder); /*while(pEngine->Decoder.tail!=NULL) remove_buf(&pEngine->Decoder); pEngine->Decoder.bsize=0; pEngine->Decoder.header_parsed=0; pEngine->Decoder.side_parsed=0; pEngine->Decoder.data_parsed=0; pEngine->Decoder.sync_bitstream=1;*/ }
static int mp3_queue(struct ast_filestream *s) { struct mp3_private *p = s->_private; int res = 0, bytes = 0; if(p->seek) { ExitMP3(&p->mp); InitMP3(&p->mp, OUTSCALE); fseek(s->f, 0, SEEK_SET); p->sbuflen = p->dbuflen = p->offset = 0; while(p->offset < p->seek) { if(mp3_squeue(s)) return -1; while(p->offset < p->seek && ((res = mp3_dqueue(s))) == MP3_OK) { for(bytes = 0 ; bytes < p->dbuflen ; bytes++) { p->dbufoffset++; p->offset++; if(p->offset >= p->seek) break; } } if(res == MP3_ERR) return -1; } p->seek = 0; return 0; } if(p->dbuflen == 0) { if(p->sbuflen) { res = mp3_dqueue(s); if(res == MP3_ERR) return -1; } if(! p->sbuflen || res != MP3_OK) { if(mp3_squeue(s)) return -1; } } 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; }
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 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); }
static int mp3_open(struct ast_filestream *s) { struct mp3_private *p = s->_private; InitMP3(&p->mp, OUTSCALE); return 0; }
int lame_decode_init(void) { (void) InitMP3(&mp); return 0; }
/*********************************************************************** * MPEG3_Reset * */ static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad) { ClearMP3Buffer(&aad->mp); InitMP3(&aad->mp); }
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 */
int lame_decode_init(MPSTR * mp) { InitMP3(mp); return 0; }
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 mp3simuinit() { InitMP3(&mp); bufplayout_i=0; bufplaystart=0; }
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; }