Пример #1
0
/* 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;
}
Пример #2
0
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;
	}
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
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;
}
Пример #7
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;
		}
	};
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
0
/* 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;
}
Пример #13
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;
}
Пример #14
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 */
Пример #15
0
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 */
Пример #16
0
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;
}
Пример #17
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, &lty);
	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);
}
Пример #18
0
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;
}
Пример #19
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 (&current_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);


}