Exemple #1
0
int MP3Decoder::mp3_decode(unsigned char const *inData, unsigned long inDataLength,
                           unsigned char *outData, unsigned long *outDataLength) {
    int result = -1;
    unsigned long curOutDataIndex = 0; // 当前已输出数据的index
    unsigned long curInDataRemaining = inDataLength;// 当前输入数据剩余数据量

    if (_isClearPreDeocodeBuffer) {
        Stream.next_frame = NULL;
        _isClearPreDeocodeBuffer = false;
    }

    /* 开始解码 */
    do {
        /* 如果缓冲区空了或不足一帧数据, 就向缓冲区填充数据 */
        if (Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN) {
            size_t BufferSize;        /* 缓冲区大小 */
            size_t Remaining;        /* 帧剩余数据 */
            unsigned char *BufferStart;    /* 头指针 */

            if (Stream.next_frame != NULL) // 还有上一帧的缓存
            {

                /* 把剩余没解码完的数据补充到这次的缓冲区中 */
                Remaining = Stream.bufend - Stream.next_frame;
                memmove(Mp3_InputBuffer, Stream.next_frame, Remaining);
                BufferStart = Mp3_InputBuffer + Remaining;
                BufferSize = INPUT_BUFFER_SIZE - Remaining;
            }
            else // 没有上一帧的缓存
            {

                /* 设置了缓冲区地址, 但还没有填充数据 */
                BufferSize = INPUT_BUFFER_SIZE;
                BufferStart = Mp3_InputBuffer;
                Remaining = 0;
            }

            /* 从输入数据中读取数据并填充缓冲区 */
            if (curInDataRemaining == 0) {
                BufferSize = 0; // 没有数据可读取
            }
            else {
                if (curInDataRemaining >= BufferSize) // 剩余的数据量满足准备读取的数据量
                {
                    memcpy(BufferStart, inData + (inDataLength - curInDataRemaining), BufferSize);
                    curInDataRemaining -= BufferSize;
                }
                else // 剩余的数据量不足,全部取 出来
                {
                    memcpy(BufferStart, inData + (inDataLength - curInDataRemaining),
                           curInDataRemaining);
                    BufferSize = curInDataRemaining;
                    curInDataRemaining = 0;
                }
            }

            if (BufferSize <= 0) // 未读取到数据,直接返回
            {
                /*printf("文件读取失败\n");
                exit(-1);*/
                result = 0;
                break;
            }

            mad_stream_buffer(&Stream, Mp3_InputBuffer, BufferSize + Remaining);
            Stream.error = MAD_ERROR_NONE;
        }


        if (mad_frame_decode(&Frame, &Stream)) {

            // 解码出错
            if (MAD_RECOVERABLE(Stream.error)) {

                // 可恢复的错误,继续执行
                continue;
            }
            else {
                if (Stream.error == MAD_ERROR_BUFLEN) {
                    continue; /* buffer解码光了, 需要继续填充 */
                }
                else if (Stream.error == MAD_ERROR_LOSTSYNC) {

                    // 丢失同步,这里可以不处理,因此该错误属于可恢复的错误
                    int tagsize = 0;
                    //tagsize = id3_tag_query(Stream.this_frame, Stream.bufend - Stream.this_frame);
                    if (tagsize > 0) {
                        mad_stream_skip(&Stream, tagsize);
                    }
                    continue;
                }
                else {
                    // 严重错误,无法继续解码
                    result = -1;
                    break;
                }
            }
        }
        /* 设置每帧的播放时间 */
        //mad_timer_add(&Timer, Frame.header.duration);
        /* 解码成音频数据 */
        mad_synth_frame(&Synth, &Frame);

        struct mad_pcm *pcm = &Synth.pcm;
        unsigned int nchannels, nsamples;
        mad_fixed_t const *left_ch, *right_ch;

        /* pcm->samplerate contains the sampling frequency */
        nchannels = pcm->channels;
        nsamples = pcm->length;
        left_ch = pcm->samples[0];
        right_ch = pcm->samples[1];

        int curDataLen = pcm->length * pcm->channels * sizeof(short);
        short *buf = (short *) malloc(curDataLen);

        // 将解码后的数据进行填充
        int i = 0;
        while (nsamples--) {
            signed int sample;
            // output sample(s) in 16-bit signed little-endian PCM
            sample = scale(*left_ch++);
            buf[i++] = sample & 0xFFFF;
            if (nchannels == 2) {
                sample = scale(*right_ch++);
                buf[i++] = sample & 0xFFFF;
            }
        }

        memcpy(outData + curOutDataIndex, buf, curDataLen);
        curOutDataIndex += curDataLen;
        *outDataLength = curOutDataIndex;

        free(buf);

    } while (1);

    return result;
}
Exemple #2
0
bool K3bMadDecoder::seekInternal( const K3b::Msf& pos )
{
    //
    // we need to reset the complete mad stuff
    //
    if( !initDecoderInternal() )
        return false;

    //
    // search a position
    // This is all hacking, I don't really know what I am doing here... ;)
    //
    double mp3FrameSecs = static_cast<double>(d->firstHeader.duration.seconds)
                          + static_cast<double>(d->firstHeader.duration.fraction) / static_cast<double>(MAD_TIMER_RESOLUTION);

    double posSecs = static_cast<double>(pos.totalFrames()) / 75.0;

    // seekPosition to seek after frame i
    unsigned int frame = static_cast<unsigned int>( posSecs / mp3FrameSecs );

    // Rob said: 29 frames is the theoretically max frame reservoir limit (whatever that means...)
    // it seems that mad needs at most 29 frames to get ready
    unsigned int frameReservoirProtect = ( frame > 29 ? 29 : frame );

    frame -= frameReservoirProtect;

    // seek in the input file behind the already decoded data
    d->handle->inputSeek( d->seekPositions[frame] );

    qDebug() << "(K3bMadDecoder) Seeking to frame " << frame << " with "
             << frameReservoirProtect << " reservoir frames." << endl;

    // decode some frames ignoring MAD_ERROR_BADDATAPTR errors
    unsigned int i = 1;
    while( i <= frameReservoirProtect ) {
        d->handle->fillStreamBuffer();
        if( mad_frame_decode( d->handle->madFrame, d->handle->madStream ) ) {
            if( MAD_RECOVERABLE( d->handle->madStream->error ) ) {
                if( d->handle->madStream->error == MAD_ERROR_BUFLEN )
                    continue;
                else if( d->handle->madStream->error != MAD_ERROR_BADDATAPTR ) {
                    qDebug() << "(K3bMadDecoder) Seeking: recoverable mad error ("
                             << mad_stream_errorstr(d->handle->madStream) << ")" << endl;
                    continue;
                }
                else {
                    qDebug() << "(K3bMadDecoder) Seeking: ignoring ("
                             << mad_stream_errorstr(d->handle->madStream) << ")" << endl;
                }
            }
            else
                return false;
        }

        if( i == frameReservoirProtect )  // synth only the last frame (Rob said so ;)
            mad_synth_frame( d->handle->madSynth, d->handle->madFrame );

        ++i;
    }

    return true;
}
int Mp3Decoder::Read(u8 * buffer, int buffer_size, int)
{
	if(!file_fd)
		return -1;

	if(Format == VOICE_STEREO_16BIT)
		buffer_size &= ~0x0003;
	else
		buffer_size &= ~0x0001;

	u8 * write_pos = buffer;
	u8 * write_end = buffer+buffer_size;

	while(1)
	{
		while(SynthPos < Synth.pcm.length)
		{
			if(write_pos >= write_end)
				return write_pos-buffer;

			*((s16 *)write_pos) = FixedToShort(Synth.pcm.samples[0][SynthPos]);
			write_pos += 2;

			if(MAD_NCHANNELS(&Frame.header) == 2)
			{
				*((s16 *)write_pos) = FixedToShort(Synth.pcm.samples[1][SynthPos]);
				write_pos += 2;
			}
			SynthPos++;
		}

		if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
		{
			u8 *ReadStart = ReadBuffer;
			int ReadSize = SoundBlockSize*SoundBlocks;
			int Remaining = 0;

			if(Stream.next_frame != NULL)
			{
				Remaining = Stream.bufend - Stream.next_frame;
				memmove(ReadBuffer, Stream.next_frame, Remaining);
				ReadStart += Remaining;
				ReadSize -= Remaining;
			}

			ReadSize = file_fd->read(ReadStart, ReadSize);
			if(ReadSize <= 0)
			{
				GuardPtr = ReadStart;
				memset(GuardPtr, 0, MAD_BUFFER_GUARD);
				ReadSize = MAD_BUFFER_GUARD;
			}

			CurPos += ReadSize;
			mad_stream_buffer(&Stream, ReadBuffer, Remaining+ReadSize);
		}

		if(mad_frame_decode(&Frame,&Stream))
		{
			if(MAD_RECOVERABLE(Stream.error))
			{
				if(Stream.error != MAD_ERROR_LOSTSYNC || !GuardPtr)
				continue;
			}
			else
			{
				if(Stream.error != MAD_ERROR_BUFLEN)
					return -1;
				else if(Stream.error == MAD_ERROR_BUFLEN && GuardPtr)
					return -1;
			}
		}

		mad_timer_add(&Timer,Frame.header.duration);
		mad_synth_frame(&Synth,&Frame);
		SynthPos = 0;
	}
}
Exemple #4
0
/*****************************************************************************
 * DoWork: decode an MPEG audio frame.
 *****************************************************************************/
static void DoWork( filter_t * p_filter,
                    block_t * p_in_buf, block_t * p_out_buf )
{
    filter_sys_t *p_sys = p_filter->p_sys;

    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
    p_out_buf->i_buffer = p_in_buf->i_nb_samples * sizeof(vlc_fixed_t) *
                               aout_FormatNbChannels( &p_filter->fmt_out.audio );

    /* Do the actual decoding now. */
    mad_stream_buffer( &p_sys->mad_stream, p_in_buf->p_buffer,
                       p_in_buf->i_buffer );
    if ( mad_frame_decode( &p_sys->mad_frame, &p_sys->mad_stream ) == -1 )
    {
        msg_Dbg( p_filter, "libmad error: %s",
                  mad_stream_errorstr( &p_sys->mad_stream ) );
        p_sys->i_reject_count = 3;
    }
    else if( p_in_buf->i_flags & BLOCK_FLAG_DISCONTINUITY )
    {
        p_sys->i_reject_count = 3;
    }

    if( p_sys->i_reject_count > 0 )
    {
        if( p_filter->fmt_out.audio.i_format == VLC_CODEC_FL32 )
        {
            int i;
            int i_size = p_out_buf->i_buffer / sizeof(float);

            float * a = (float *)p_out_buf->p_buffer;
            for ( i = 0 ; i < i_size ; i++ )
                *a++ = 0.0;
        }
        else
        {
            memset( p_out_buf->p_buffer, 0, p_out_buf->i_buffer );
        }
        p_sys->i_reject_count--;
        return;
    }


    mad_synth_frame( &p_sys->mad_synth, &p_sys->mad_frame );

    struct mad_pcm * p_pcm = &p_sys->mad_synth.pcm;
    unsigned int i_samples = p_pcm->length;
    mad_fixed_t const * p_left = p_pcm->samples[0];
    mad_fixed_t const * p_right = p_pcm->samples[1];

    assert( i_samples == p_out_buf->i_nb_samples );
    if ( p_filter->fmt_out.audio.i_format == VLC_CODEC_FI32 )
    {
        /* Interleave and keep buffers in mad_fixed_t format */
        mad_fixed_t * p_samples = (mad_fixed_t *)p_out_buf->p_buffer;

        if ( p_pcm->channels == 2 )
        {
            while ( i_samples-- )
            {
                *p_samples++ = *p_left++;
                *p_samples++ = *p_right++;
            }
        }
        else
        {
            assert( p_pcm->channels == 1 );
            vlc_memcpy( p_samples, p_left, i_samples * sizeof(mad_fixed_t) );
        }
    }
    else
    {
        /* float32 */
        float * p_samples = (float *)p_out_buf->p_buffer;
        const float f_temp = (float)FIXED32_ONE;

        if ( p_pcm->channels == 2 )
        {
            while ( i_samples-- )
            {
                *p_samples++ = (float)*p_left++ / f_temp;
                *p_samples++ = (float)*p_right++ / f_temp;
            }
        }
        else
        {
            assert( p_pcm->channels == 1 );
            while ( i_samples-- )
            {
                *p_samples++ = (float)*p_left++ / f_temp;
            }
        }
    }
}
Exemple #5
0
/*	mp3 playback callback
 */
static WaitressCbReturn_t BarPlayerMp3Cb (void *ptr, size_t size,
		void *stream) {
	const char *data = ptr;
	struct audioPlayer *player = stream;
	size_t i;

	QUIT_PAUSE_CHECK;

	if (!BarPlayerBufferFill (player, data, size)) {
		return WAITRESS_CB_RET_ERR;
	}

	/* some "prebuffering" */
	if (player->mode < PLAYER_RECV_DATA &&
			player->bufferFilled < BAR_PLAYER_BUFSIZE / 2) {
		return WAITRESS_CB_RET_OK;
	}

	mad_stream_buffer (&player->mp3Stream, player->buffer,
			player->bufferFilled);
	player->mp3Stream.error = 0;
	do {
		/* channels * max samples, found in mad.h */
		signed short int madDecoded[2*1152], *madPtr = madDecoded;

		if (mad_frame_decode (&player->mp3Frame, &player->mp3Stream) != 0) {
			if (player->mp3Stream.error != MAD_ERROR_BUFLEN) {
				BarUiMsg (player->settings, MSG_ERR,
						"mp3 decoding error: %s\n",
						mad_stream_errorstr (&player->mp3Stream));
				return WAITRESS_CB_RET_ERR;
			} else {
				/* rebuffering required => exit loop */
				break;
			}
		}
		mad_synth_frame (&player->mp3Synth, &player->mp3Frame);
		for (i = 0; i < player->mp3Synth.pcm.length; i++) {
			/* left channel */
			*(madPtr++) = applyReplayGain (BarPlayerMadToShort (
					player->mp3Synth.pcm.samples[0][i]), player->scale);

			/* right channel */
			*(madPtr++) = applyReplayGain (BarPlayerMadToShort (
					player->mp3Synth.pcm.samples[1][i]), player->scale);
		}
		if (player->mode < PLAYER_AUDIO_INITIALIZED) {
			ao_sample_format format;
			int audioOutDriver;

			player->channels = player->mp3Synth.pcm.channels;
			player->samplerate = player->mp3Synth.pcm.samplerate;
			audioOutDriver = ao_default_driver_id();
			memset (&format, 0, sizeof (format));
			format.bits = 16;
			format.channels = player->channels;
			format.rate = player->samplerate;
			format.byte_format = AO_FMT_NATIVE;
			if ((player->audioOutDevice = ao_open_live (audioOutDriver,
					&format, NULL)) == NULL) {
				player->aoError = 1;
				BarUiMsg (player->settings, MSG_ERR,
						"Cannot open audio device\n");
				return WAITRESS_CB_RET_ERR;
			}

			/* calc song length using the framerate of the first decoded frame */
			player->songDuration = (unsigned long long int) player->waith.request.contentLength /
					((unsigned long long int) player->mp3Frame.header.bitrate /
					(unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR / 8LL);

			/* must be > PLAYER_SAMPLESIZE_INITIALIZED, otherwise time won't
			 * be visible to user (ugly, but mp3 decoding != aac decoding) */
			player->mode = PLAYER_RECV_DATA;
		}
		/* samples * length * channels */
		ao_play (player->audioOutDevice, (char *) madDecoded,
				player->mp3Synth.pcm.length * 2 * 2);

		/* avoid division by 0 */
		if (player->mode == PLAYER_RECV_DATA) {
			/* same calculation as in aac player; don't need to divide by
			 * channels, length is number of samples for _one_ channel */
			player->songPlayed += (unsigned long long int) player->mp3Synth.pcm.length *
					(unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR /
					(unsigned long long int) player->samplerate;
		}

		QUIT_PAUSE_CHECK;
	} while (player->mp3Stream.error != MAD_ERROR_BUFLEN);

	player->bufferRead += player->mp3Stream.next_frame - player->buffer;

	BarPlayerBufferMove (player);

	return WAITRESS_CB_RET_OK;
}
Exemple #6
0
static void MP3Update(void)
{
	int flip;
	UINT8 *GuardPtr;
	INT16 *OutputPtr, *OutputEnd;
	struct mad_stream Stream;
	struct mad_frame Frame;
	struct mad_synth Synth;
	mad_timer_t Timer;

	mad_stream_init(&Stream);
	mad_frame_init(&Frame);
	mad_synth_init(&Synth);
	mad_timer_reset(&Timer);

	OutputPtr = (INT16 *)mp3_out[0];
	OutputEnd = (INT16 *)(mp3_out[0] + MP3_BUFFER_SIZE);
	GuardPtr = NULL;

	mp3_filepos = 0;
	mp3_frame = 0;
	flip = 0;
	cdda_command_ack = 1;

	while (mp3_active && mp3_status != MP3_STOP)
	{
		if (Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
		{
			UINT32 ReadSize, Remaining;
			UINT8 *ReadStart;

			if (Stream.next_frame != NULL)
			{
				Remaining = Stream.bufend - Stream.next_frame;
				ReadStart = mp3_in + Remaining;
				ReadSize  = (2 * MP3_BUFFER_SIZE) - Remaining;
				memmove(mp3_in, Stream.next_frame, Remaining);
			}
			else
			{
				ReadSize  = 2 * MP3_BUFFER_SIZE;
				ReadStart = mp3_in;
				Remaining = 0;
			}

			if (MP3SleepCheck()) break;

			ReadSize = sceIoRead(mp3_fd, ReadStart, ReadSize);
			mp3_filepos += ReadSize;
			if (mp3_filepos == mp3_fsize)
			{
				if (cdda_autoloop)
				{
					mp3_filepos = 0;
					sceIoLseek(mp3_fd, 0, PSP_SEEK_SET);
				}
				else
				{
					cdda_playing = CDDA_STOP;
					mp3_status = MP3_STOP;
				}
			}

			if (mp3_filepos == mp3_fsize)
			{
				GuardPtr = ReadStart + ReadSize;
				memset(GuardPtr, 0, MAD_BUFFER_GUARD);
				ReadSize += MAD_BUFFER_GUARD;
			}

			mad_stream_buffer(&Stream, mp3_in, ReadSize + Remaining);

			Stream.error = 0;
		}

		if (mad_frame_decode(&Frame, &Stream))
		{
			if (MAD_RECOVERABLE(Stream.error))
			{
//				if (Stream.error != MAD_ERROR_LOSTSYNC || Stream.this_frame != GuardPtr)
				continue;
			}
			else if (Stream.error == MAD_ERROR_BUFLEN)
			{
				continue;
			}
			else
			{
				ui_popup(TEXT(MP3_DECODE_ERROR));
				mp3_status = MP3_STOP;
				break;
			}
		}

		mp3_frame++;
		mad_timer_add(&Timer, Frame.header.duration);
		mad_synth_frame(&Synth, &Frame);

		if (mp3_status == MP3_PLAY)
		{
			int i;

			for (i = 0; i < Synth.pcm.length; i++)
			{
				if (MAD_NCHANNELS(&Frame.header) == 2)
				{
					*OutputPtr++ = MP3Limit(Synth.pcm.samples[0][i]);
					*OutputPtr++ = MP3Limit(Synth.pcm.samples[1][i]);
				}
				else
				{
					INT16 data = MP3Limit(Synth.pcm.samples[0][i]);

					*OutputPtr++ = data;
					*OutputPtr++ = data;
				}

				if (OutputPtr == OutputEnd)
				{
					sceAudioOutputPannedBlocking(mp3_handle, mp3_volume, mp3_volume, mp3_out[flip]);
					flip ^= 1;
					OutputPtr = (INT16 *)mp3_out[flip];
					OutputEnd = (INT16 *)(mp3_out[flip] + MP3_BUFFER_SIZE);
				}
			}
		}
		else if (mp3_status == MP3_SEEK)
		{
			if (mp3_frame >= mp3_start_frame)
			{
				mp3_start_frame = 0;
				mp3_status = MP3_SLEEP;
				sceKernelSleepThread();
			}
		}
	}

	mad_synth_finish(&Synth);
	mad_frame_finish(&Frame);
	mad_stream_finish(&Stream);

	if (mp3_fd >= 0)
	{
		sceIoClose(mp3_fd);
		mp3_fd = -1;
	}
}
Exemple #7
0
static gint
xmms_mad_read (xmms_xform_t *xform, gpointer buf, gint len, xmms_error_t *err)
{
	xmms_mad_data_t *data;
	xmms_samples16_t *out = (xmms_samples16_t *)buf;
	gint ret;
	gint j;
	gint read = 0;

	data = xmms_xform_private_data_get (xform);

	j = 0;

	while (read < len) {

		/* use already synthetized frame first */
		if (data->synthpos < data->synth.pcm.length) {
			out[j++] = scale_linear (data->synth.pcm.samples[0][data->synthpos]);
			if (data->channels == 2) {
				out[j++] = scale_linear (data->synth.pcm.samples[1][data->synthpos]);
				read += 2 * xmms_sample_size_get (XMMS_SAMPLE_FORMAT_S16);
			} else {
				read += xmms_sample_size_get (XMMS_SAMPLE_FORMAT_S16);
			}
			data->synthpos++;
			continue;
		}

		/* then try to decode another frame */
		if (mad_frame_decode (&data->frame, &data->stream) != -1) {

			/* mad_synthpop_frame - go Depeche! */
			mad_synth_frame (&data->synth, &data->frame);

			if (data->frames_to_skip) {
				data->frames_to_skip--;
				data->synthpos = 0x7fffffff;
			} else if (data->samples_to_skip) {
				if (data->samples_to_skip > data->synth.pcm.length) {
					data->synthpos = 0x7fffffff;
					data->samples_to_skip -= data->synth.pcm.length;
				} else {
					data->synthpos = data->samples_to_skip;
					data->samples_to_skip = 0;
				}
			} else {
				if (data->samples_to_play == 0) {
					return read;
				} else if (data->samples_to_play > 0) {
					if (data->synth.pcm.length > data->samples_to_play) {
						data->synth.pcm.length = data->samples_to_play;
					}
					data->samples_to_play -= data->synth.pcm.length;
				}
				data->synthpos = 0;
			}
			continue;
		}


		/* if there is no frame to decode stream more data */
		if (data->stream.next_frame) {
			guchar *buffer = data->buffer;
			const guchar *nf = data->stream.next_frame;
			memmove (data->buffer, data->stream.next_frame,
			         data->buffer_length = (&buffer[data->buffer_length] - nf));
		}

		ret = xmms_xform_read (xform,
		                       (gchar *)data->buffer + data->buffer_length,
		                       4096 - data->buffer_length,
		                       err);

		if (ret <= 0) {
			return ret;
		}

		data->buffer_length += ret;
		mad_stream_buffer (&data->stream, data->buffer, data->buffer_length);
	}

	return read;
}
Exemple #8
0
unsigned int mpgDecoder::decode( float *** data, int count )
{
#ifdef HAVE_MAD
        if(data)
		*data=returnBuffer;

	while( mad_outputBuffer[0].canWrite(1152) )  // well letts refill the Input buffer..........
	{
		if( madStream->buffer == NULL || madStream->error == MAD_ERROR_BUFLEN)  // well letts refill the Input buffer..........
		{
			size_t readSize, remaining;
			unsigned char* readStart;
			unsigned char* guardPtr;

			if( madFile->atEnd() )
				return(0);

			if(madStream->next_frame)  // move remaining bytes to start wich has not been decoded yet...
			{
				remaining = mad_inputBuffer + 163840 - madStream->next_frame;
				memmove( mad_inputBuffer, madStream->next_frame, remaining );
				readStart = mad_inputBuffer + remaining;
				readSize = 163840 - remaining;
			}
			else
			{
				readSize = 163840;
				readStart = mad_inputBuffer;
				remaining = 0;
			}

			// get some more Byte from File...
			unsigned int readCnt = 0;
			while( !madFile->atEnd() && readCnt < readSize)
			{
                            readStart[readCnt] = madFile->read(1).at(0);
                            readCnt++;
			}
			
                        //bei EOF ein paar GUARD 0Bytes anhaengen die MAD benötigt..
			if( madFile->atEnd() )
			{
				guardPtr = readStart + readCnt;
				memset( guardPtr, 0, MAD_BUFFER_GUARD);
				readCnt += MAD_BUFFER_GUARD;
			}
			mad_stream_buffer( madStream, mad_inputBuffer, readCnt+remaining);
			madStream->error = MAD_ERROR_NONE;
		}

		// well lets decode the buffer and get some Music out of it :-)
		mad_frame_decode( madFrame, madStream );
		frameCounter++;

		// first MPeg Frame isnt Played cause it contains noisy Metadata if we Play it :D
		// frame is also not played if we could not decode the whole MPeg frame in case of end of input buffer
		if(madStream->error==MAD_ERROR_BUFLEN || frameCounter ==1)
			continue;

        mad_timer_add( currentPositionTimer, madFrame->header.duration );
		mad_synth_frame( madSynth, madFrame );

		// decoding done.. convert sampletype...
		for( unsigned int j=0; j<channels; j++ )
			for(unsigned int i=0; i<madSynth->pcm.length; i++ )
			{
                                float temp = scale( madSynth->pcm.samples[j][i]);
                                mad_outputBuffer[j].write( &temp, 1 );
                        }
	}
	//nice little workarround so the buffer never gets so much back it wants to....
	int dataAvailable = mad_outputBuffer[0].canRead(count*.95)?count*.95:mad_outputBuffer[0].getAvailable()-8;

        // ensure the return buffer is clean...
        memset(returnBuffer[0], 0, 8192*sizeof(float));
        memset(returnBuffer[1], 0, 8192*sizeof(float));

        for( unsigned int j=0; j<channels; j++ )
		mad_outputBuffer[j].read( returnBuffer[j], dataAvailable );

        return dataAvailable;
#endif
}
Exemple #9
0
int MAD_WRAPPER_playAudio( void *userdata, Uint8 *stream, int len )
{
    MAD_WRAPPER *mad = (MAD_WRAPPER*)userdata;

    if ( !mad->is_playing ) return -1; // pause
    
    size_t         ReadSize = 1, Remaining;
    unsigned char  *ReadStart;

    do{
        if( mad->Stream.buffer==NULL || mad->Stream.error==MAD_ERROR_BUFLEN ){
    
            if ( mad->Stream.next_frame != NULL ){
                Remaining = mad->Stream.bufend - mad->Stream.next_frame;
                memmove( mad->input_buf, mad->Stream.next_frame, Remaining);
                ReadStart = mad->input_buf + Remaining;
                ReadSize  = INPUT_BUFFER_SIZE - Remaining;
            }
            else{
                ReadSize  = INPUT_BUFFER_SIZE;
                ReadStart = mad->input_buf;
                Remaining = 0;
            }

            ReadSize = SDL_RWread( mad->src, ReadStart, 1, ReadSize );
            if ( ReadSize <= 0 ) break; // end of stream

            mad_stream_buffer( &mad->Stream, mad->input_buf, ReadSize + Remaining );
            mad->Stream.error = MAD_ERROR_NONE;
        }

        if ( mad_frame_decode( &mad->Frame,&mad->Stream ) ){
            if ( MAD_RECOVERABLE( mad->Stream.error ) ||
                 mad->Stream.error == MAD_ERROR_BUFLEN ){
                continue;
            }
            else{
                fprintf( stderr, "unrecoverable frame level error (%s).\n",
                         mad_stream_errorstr(&mad->Stream) );
                return 0; // error
            }
        }

#if defined(PDA) && !defined(PSP) && !defined(IPHONE)
        if ( mad->Frame.header.samplerate == 44100 )
            mad->Frame.options |= MAD_OPTION_HALFSAMPLERATE;
#endif
        mad_synth_frame( &mad->Synth, &mad->Frame );
    
        char *ptr = (char*)mad->output_buf + mad->output_buf_index;

        for ( int i=0 ; i<mad->Synth.pcm.length ; i++ ){
            unsigned short	Sample;

            /* Left channel */
            Sample=MadFixedToUshort( mad->Synth.pcm.samples[0][i] );
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
            *(ptr++) = Sample & 0xff;
            *(ptr++) = Sample >> 8;
#else
            *(ptr++) = Sample >> 8;
            *(ptr++) = Sample & 0xff;
#endif

            /* Right channel, if exist. */
            if ( MAD_NCHANNELS(&mad->Frame.header)==2 )
                Sample=MadFixedToUshort( mad->Synth.pcm.samples[1][i] );
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
            *(ptr++) = Sample & 0xff;
            *(ptr++) = Sample >> 8;
#else
            *(ptr++) = Sample >> 8;
            *(ptr++) = Sample&0xff;
#endif
        }
        mad->output_buf_index += mad->Synth.pcm.length * 4;
    }
    while( mad->output_buf_index < len );

    if ( ReadSize <= 0 ) return 0; // end of stream

    if ( mad->output_buf_index > len ){
        SDL_MixAudio( stream, mad->output_buf, len, mad->volume );
        memmove( mad->output_buf, mad->output_buf + len, mad->output_buf_index - len );
        mad->output_buf_index -= len;
    }
    else{
        SDL_MixAudio( stream, mad->output_buf, mad->output_buf_index, mad->volume );
        len = mad->output_buf_index;
        mad->output_buf_index = 0;
    }

    return len;
}
Exemple #10
0
/*****************************************************************************
 * DoWork: decode an MPEG audio frame.
 *****************************************************************************/
static void DoWork( filter_t * p_filter,
                    block_t * p_in_buf, block_t * p_out_buf )
{
    filter_sys_t *p_sys = p_filter->p_sys;

    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
    p_out_buf->i_buffer = p_in_buf->i_nb_samples * sizeof(float) *
                               aout_FormatNbChannels( &p_filter->fmt_out.audio );

    /* Do the actual decoding now. */
    mad_stream_buffer( &p_sys->mad_stream, p_in_buf->p_buffer,
                       p_in_buf->i_buffer );
    if ( mad_frame_decode( &p_sys->mad_frame, &p_sys->mad_stream ) == -1 )
    {
        msg_Err( p_filter, "libmad error: %s",
                  mad_stream_errorstr( &p_sys->mad_stream ) );
        if( !MAD_RECOVERABLE( p_sys->mad_stream.error ) )
            p_sys->i_reject_count = 3;
    }
    else if( p_in_buf->i_flags & BLOCK_FLAG_DISCONTINUITY )
    {
        p_sys->i_reject_count = 3;
    }

    if( p_sys->i_reject_count > 0 )
    {
reject:
        memset( p_out_buf->p_buffer, 0, p_out_buf->i_buffer );
        p_sys->i_reject_count--;
        return;
    }


    mad_synth_frame( &p_sys->mad_synth, &p_sys->mad_frame );

    struct mad_pcm * p_pcm = &p_sys->mad_synth.pcm;
    unsigned int i_samples = p_pcm->length;
    mad_fixed_t const * p_left = p_pcm->samples[0];
    mad_fixed_t const * p_right = p_pcm->samples[1];
    float *p_samples = (float *)p_out_buf->p_buffer;

    if (p_pcm->channels > p_filter->fmt_out.audio.i_channels)
    {
        msg_Err( p_filter, "wrong channels count (corrupt stream?): %u > %u",
                 p_pcm->channels, p_filter->fmt_out.audio.i_channels);
        p_sys->i_reject_count = 3;
        goto reject;
    }

    if( i_samples != p_out_buf->i_nb_samples )
    {
        msg_Err( p_filter, "unexpected samples count (corrupt stream?): "
                 "%u / %u", i_samples, p_out_buf->i_nb_samples );
        p_sys->i_reject_count = 3;
        goto reject;
    }

    /* Interleave and keep buffers in mad_fixed_t format */
    if ( p_pcm->channels == 2 )
    {
        while ( i_samples-- )
        {
            //assert( *p_left < MAD_F_ONE );
            //assert( *p_left >= -MAD_F_ONE );
            //assert( *p_right < MAD_F_ONE );
            //assert( *p_right >= -MAD_F_ONE );
            *p_samples++ = (float)*p_left++ / (float)MAD_F_ONE;
            *p_samples++ = (float)*p_right++ / (float)MAD_F_ONE;
        }
    }
    else
    {
        assert( p_pcm->channels == 1 );
        while ( i_samples-- )
        {
            //assert( *p_left < MAD_F_ONE );
            //assert( *p_left >= -MAD_F_ONE );
            *p_samples++ = (float)*p_left++ / (float)MAD_F_ONE;
        }
    }
}
void
MADTranscode::processData( const QByteArray &buffer, bool finish )
{
    static audio_dither left_dither, right_dither;

    int err = 0;
    m_encodedBuffer.append( buffer );

    while ( err == 0 && ( m_encodedBuffer.count() >= MP3_BUFFER || finish ) )
    {
        mad_stream_buffer( &stream, (const unsigned char*)m_encodedBuffer.data(), m_encodedBuffer.count() );
        err = mad_frame_decode( &frame, &stream );

        if ( stream.next_frame != 0 )
        {
            size_t r = stream.next_frame - stream.buffer;
            m_encodedBuffer.remove( 0, r );
        }

        if ( err )
        {
//             if ( stream.error != MAD_ERROR_LOSTSYNC )
//                 qDebug() << "libmad error:" << mad_stream_errorstr( &stream );

            if ( !MAD_RECOVERABLE( stream.error ) )
                return;

            err = 0;
        }
        else
        {
            mad_timer_add( &timer, frame.header.duration );
            mad_synth_frame( &synth, &frame );

            if ( !m_mpegInitialised )
            {
                long sampleRate = synth.pcm.samplerate;
                int channels = synth.pcm.channels;

                qDebug() << "madTranscode( Samplerate:" << sampleRate << "- Channels:" << channels << ")";

                m_mpegInitialised = true;
                emit streamInitialized( sampleRate, channels > 0 ? channels : 2 );
            }

            for ( int i = 0; i < synth.pcm.length; i++ )
            {
                union PCMDATA
                {
                    short i;
                    unsigned char b[2];
                } pcmData;

                pcmData.i = dither( synth.pcm.samples[0][i], &left_dither );
                m_decodedBuffer.append( pcmData.b[0] );
                m_decodedBuffer.append( pcmData.b[1] );

                if ( synth.pcm.channels == 2 )
                {
                    pcmData.i = dither( synth.pcm.samples[1][i], &right_dither );
                    m_decodedBuffer.append( pcmData.b[0] );
                    m_decodedBuffer.append( pcmData.b[1] );
                }
            }

            if ( timer.seconds != last_timer.seconds )
                emit timeChanged( timer.seconds );

            last_timer = timer;
        }
    }
}
Exemple #12
0
/****************************************************************************
 * Main decoding loop. This is where mad is used.							*
 ****************************************************************************/
#define INPUT_BUFFER_SIZE	(5*8192)
#define OUTPUT_BUFFER_SIZE	8192 /* Must be an integer multiple of 4. */
static int MpegAudioDecoder(FILE *InputFp, FILE *OutputFp)
{
	struct mad_stream	Stream;
	struct mad_frame	Frame;
	struct mad_synth	Synth;
	mad_timer_t			Timer;
	unsigned char		InputBuffer[INPUT_BUFFER_SIZE+MAD_BUFFER_GUARD],
						OutputBuffer[OUTPUT_BUFFER_SIZE],
						*OutputPtr=OutputBuffer,
						*GuardPtr=NULL;
	const unsigned char	*OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE;
	int					Status=0,
						i;
	unsigned long		FrameCount=0;
	bstdfile_t			*BstdFile;

	/* First the structures used by libmad must be initialized. */
	mad_stream_init(&Stream);
	mad_frame_init(&Frame);
	mad_synth_init(&Synth);
	mad_timer_reset(&Timer);

	/* Decoding options can here be set in the options field of the
	 * Stream structure.
	 */

	/* {1} When decoding from a file we need to know when the end of
	 * the file is reached at the same time as the last bytes are read
	 * (see also the comment marked {3} bellow). Neither the standard
	 * C fread() function nor the POSIX read() system call provides
	 * this feature. We thus need to perform our reads through an
	 * interface having this feature, this is implemented here by the
	 * bstdfile.c module.
	 */
	BstdFile=NewBstdFile(InputFp);
	if(BstdFile==NULL)
	{
		fprintf(stderr,"%s: can't create a new bstdfile_t (%s).\n",
				ProgName,strerror(errno));
		return(1);
	}

	/* This is the decoding loop. */
	do
	{
		/* The input bucket must be filled if it becomes empty or if
		 * it's the first execution of the loop.
		 */
		if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN)
		{
			size_t			ReadSize,
							Remaining;
			unsigned char	*ReadStart;

			/* {2} libmad may not consume all bytes of the input
			 * buffer. If the last frame in the buffer is not wholly
			 * contained by it, then that frame's start is pointed by
			 * the next_frame member of the Stream structure. This
			 * common situation occurs when mad_frame_decode() fails,
			 * sets the stream error code to MAD_ERROR_BUFLEN, and
			 * sets the next_frame pointer to a non NULL value. (See
			 * also the comment marked {4} bellow.)
			 *
			 * When this occurs, the remaining unused bytes must be
			 * put back at the beginning of the buffer and taken in
			 * account before refilling the buffer. This means that
			 * the input buffer must be large enough to hold a whole
			 * frame at the highest observable bit-rate (currently 448
			 * kb/s). XXX=XXX Is 2016 bytes the size of the largest
			 * frame? (448000*(1152/32000))/8
			 */
			if(Stream.next_frame!=NULL)
			{
				Remaining=Stream.bufend-Stream.next_frame;
				memmove(InputBuffer,Stream.next_frame,Remaining);
				ReadStart=InputBuffer+Remaining;
				ReadSize=INPUT_BUFFER_SIZE-Remaining;
			}
			else
				ReadSize=INPUT_BUFFER_SIZE,
					ReadStart=InputBuffer,
					Remaining=0;

			/* Fill-in the buffer. If an error occurs print a message
			 * and leave the decoding loop. If the end of stream is
			 * reached we also leave the loop but the return status is
			 * left untouched.
			 */
			ReadSize=BstdRead(ReadStart,1,ReadSize,BstdFile);
			if(ReadSize<=0)
			{
				if(ferror(InputFp))
				{
					fprintf(stderr,"%s: read error on bit-stream (%s)\n",
							ProgName,strerror(errno));
					Status=1;
				}
				if(feof(InputFp))
					fprintf(stderr,"%s: end of input stream\n",ProgName);
				break;
			}

			/* {3} When decoding the last frame of a file, it must be
			 * followed by MAD_BUFFER_GUARD zero bytes if one wants to
			 * decode that last frame. When the end of file is
			 * detected we append that quantity of bytes at the end of
			 * the available data. Note that the buffer can't overflow
			 * as the guard size was allocated but not used the the
			 * buffer management code. (See also the comment marked
			 * {1}.)
			 *
			 * In a message to the mad-dev mailing list on May 29th,
			 * 2001, Rob Leslie explains the guard zone as follows:
			 *
			 *    "The reason for MAD_BUFFER_GUARD has to do with the
			 *    way decoding is performed. In Layer III, Huffman
			 *    decoding may inadvertently read a few bytes beyond
			 *    the end of the buffer in the case of certain invalid
			 *    input. This is not detected until after the fact. To
			 *    prevent this from causing problems, and also to
			 *    ensure the next frame's main_data_begin pointer is
			 *    always accessible, MAD requires MAD_BUFFER_GUARD
			 *    (currently 8) bytes to be present in the buffer past
			 *    the end of the current frame in order to decode the
			 *    frame."
			 */
			if(BstdFileEofP(BstdFile))
			{
				GuardPtr=ReadStart+ReadSize;
				memset(GuardPtr,0,MAD_BUFFER_GUARD);
				ReadSize+=MAD_BUFFER_GUARD;
			}

			/* Pipe the new buffer content to libmad's stream decoder
             * facility.
			 */
			mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining);
			Stream.error=0;
		}

		/* Decode the next MPEG frame. The streams is read from the
		 * buffer, its constituents are break down and stored the the
		 * Frame structure, ready for examination/alteration or PCM
		 * synthesis. Decoding options are carried in the Frame
		 * structure from the Stream structure.
		 *
		 * Error handling: mad_frame_decode() returns a non zero value
		 * when an error occurs. The error condition can be checked in
		 * the error member of the Stream structure. A mad error is
		 * recoverable or fatal, the error status is checked with the
		 * MAD_RECOVERABLE macro.
		 *
		 * {4} When a fatal error is encountered all decoding
		 * activities shall be stopped, except when a MAD_ERROR_BUFLEN
		 * is signaled. This condition means that the
		 * mad_frame_decode() function needs more input to complete
		 * its work. One shall refill the buffer and repeat the
		 * mad_frame_decode() call. Some bytes may be left unused at
		 * the end of the buffer if those bytes forms an incomplete
		 * frame. Before refilling, the remaining bytes must be moved
		 * to the beginning of the buffer and used for input for the
		 * next mad_frame_decode() invocation. (See the comments
		 * marked {2} earlier for more details.)
		 *
		 * Recoverable errors are caused by malformed bit-streams, in
		 * this case one can call again mad_frame_decode() in order to
		 * skip the faulty part and re-sync to the next frame.
		 */
		if(mad_frame_decode(&Frame,&Stream))
		{
			if(MAD_RECOVERABLE(Stream.error))
			{
				/* Do not print a message if the error is a loss of
				 * synchronization and this loss is due to the end of
				 * stream guard bytes. (See the comments marked {3}
				 * supra for more informations about guard bytes.)
				 */
				if(Stream.error!=MAD_ERROR_LOSTSYNC ||
				   Stream.this_frame!=GuardPtr)
				{
					fprintf(stderr,"%s: recoverable frame level error (%s)\n",
							ProgName,MadErrorString(&Stream));
					fflush(stderr);
				}
				continue;
			}
			else
				if(Stream.error==MAD_ERROR_BUFLEN)
					continue;
				else
				{
					fprintf(stderr,"%s: unrecoverable frame level error (%s).\n",
							ProgName,MadErrorString(&Stream));
					Status=1;
					break;
				}
		}

		/* The characteristics of the stream's first frame is printed
		 * on stderr. The first frame is representative of the entire
		 * stream.
		 */
		if(FrameCount==0)
			if(PrintFrameInfo(stderr,&Frame.header))
			{
				Status=1;
				break;
			}

		/* Accounting. The computed frame duration is in the frame
		 * header structure. It is expressed as a fixed point number
		 * whole data type is mad_timer_t. It is different from the
		 * samples fixed point format and unlike it, it can't directly
		 * be added or subtracted. The timer module provides several
		 * functions to operate on such numbers. Be careful there, as
		 * some functions of libmad's timer module receive some of
		 * their mad_timer_t arguments by value!
		 */
		FrameCount++;
		mad_timer_add(&Timer,Frame.header.duration);

		/* Between the frame decoding and samples synthesis we can
		 * perform some operations on the audio data. We do this only
		 * if some processing was required. Detailed explanations are
		 * given in the ApplyFilter() function.
		 */
		if(DoFilter)
			ApplyFilter(&Frame);

		/* Once decoded the frame is synthesized to PCM samples. No errors
		 * are reported by mad_synth_frame();
		 */
		mad_synth_frame(&Synth,&Frame);

		/* Synthesized samples must be converted from libmad's fixed
		 * point number to the consumer format. Here we use unsigned
		 * 16 bit big endian integers on two channels. Integer samples
		 * are temporarily stored in a buffer that is flushed when
		 * full.
		 */
		for(i=0;i<Synth.pcm.length;i++)
		{
			signed short	Sample;

			/* Left channel */
			Sample=MadFixedToSshort(Synth.pcm.samples[0][i]);
			*(OutputPtr++)=Sample>>8;
			*(OutputPtr++)=Sample&0xff;

			/* Right channel. If the decoded stream is monophonic then
			 * the right output channel is the same as the left one.
			 */
			if(MAD_NCHANNELS(&Frame.header)==2)
				Sample=MadFixedToSshort(Synth.pcm.samples[1][i]);
			*(OutputPtr++)=Sample>>8;
			*(OutputPtr++)=Sample&0xff;

			/* Flush the output buffer if it is full. */
			if(OutputPtr==OutputBufferEnd)
			{
				if(fwrite(OutputBuffer,1,OUTPUT_BUFFER_SIZE,OutputFp)!=OUTPUT_BUFFER_SIZE)
				{
					fprintf(stderr,"%s: PCM write error (%s).\n",
							ProgName,strerror(errno));
					Status=2;
					break;
				}
				OutputPtr=OutputBuffer;
			}
		}
	}while(1);

	/* The input file was completely read; the memory allocated by our
	 * reading module must be reclaimed.
	 */
	BstdFileDestroy(BstdFile);

	/* Mad is no longer used, the structures that were initialized must
     * now be cleared.
	 */
	mad_synth_finish(&Synth);
	mad_frame_finish(&Frame);
	mad_stream_finish(&Stream);

	/* If the output buffer is not empty and no error occurred during
     * the last write, then flush it.
	 */
	if(OutputPtr!=OutputBuffer && Status!=2)
	{
		size_t	BufferSize=OutputPtr-OutputBuffer;

		if(fwrite(OutputBuffer,1,BufferSize,OutputFp)!=BufferSize)
		{
			fprintf(stderr,"%s: PCM write error (%s).\n",
					ProgName,strerror(errno));
			Status=2;
		}
	}

	/* Accounting report if no error occurred. */
	if(!Status)
	{
		char	Buffer[80];

		/* The duration timer is converted to a human readable string
		 * with the versatile, but still constrained mad_timer_string()
		 * function, in a fashion not unlike strftime(). The main
		 * difference is that the timer is broken into several
		 * values according some of it's arguments. The units and
		 * fracunits arguments specify the intended conversion to be
		 * executed.
		 *
		 * The conversion unit (MAD_UNIT_MINUTES in our example) also
		 * specify the order and kind of conversion specifications
		 * that can be used in the format string.
		 *
		 * It is best to examine libmad's timer.c source-code for details
		 * of the available units, fraction of units, their meanings,
		 * the format arguments, etc.
		 */
		mad_timer_string(Timer,Buffer,"%lu:%02lu.%03u",
						 MAD_UNITS_MINUTES,MAD_UNITS_MILLISECONDS,0);
		fprintf(stderr,"%s: %lu frames decoded (%s).\n",
				ProgName,FrameCount,Buffer);
	}

	/* That's the end of the world (in the H. G. Wells way). */
	return(Status);
}
Exemple #13
0
  /* scale */
  return output >> scalebits;
}

#define INPUT_BUFFER_SIZE  (5*8192)
#define OUTPUT_BUFFER_SIZE  8192 /* Must be an integer multiple of 4. */
void real_mpeg_play(char* fname)
{
    unsigned char InputBuffer[INPUT_BUFFER_SIZE],
        OutputBuffer[OUTPUT_BUFFER_SIZE],
        *OutputPtr=OutputBuffer;
    const unsigned char  *OutputBufferEnd=OutputBuffer+OUTPUT_BUFFER_SIZE;
    int Status=0, i, fd;
    unsigned long FrameCount=0;
    sound_t sound;
    struct mp3entry mp3;
    static struct dither d0, d1;
    int key=0;
  
    mp3info(&mp3, fname, false); /* FIXME: honor the v1first setting */

    init_sound(&sound);

    /* Configure sound device for this file - always select Stereo because
       some sound cards don't support mono */
    config_sound(&sound,mp3.frequency,2);

    if ((fd=open(fname,O_RDONLY)) < 0) {
        fprintf(stderr,"could not open %s\n",fname);
        return;
    }

    /* First the structures used by libmad must be initialized. */
    mad_stream_init(&Stream);
    mad_frame_init(&Frame);
    mad_synth_init(&Synth);
    mad_timer_reset(&Timer);

    do {
        if (Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN) {
            size_t ReadSize,Remaining;
            unsigned char *ReadStart;

            if(Stream.next_frame!=NULL) {
                Remaining=Stream.bufend-Stream.next_frame;
                memmove(InputBuffer,Stream.next_frame,Remaining);
                ReadStart=InputBuffer+Remaining;
                ReadSize=INPUT_BUFFER_SIZE-Remaining;
            } else {
                ReadSize=INPUT_BUFFER_SIZE,
                    ReadStart=InputBuffer,
                    Remaining=0;
            }

            if ((int)(ReadSize=read(fd,ReadStart,ReadSize)) < 0) {
                fprintf(stderr,"end of input stream\n");
                break;
            }

            mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining);
            Stream.error=0;
        }

        if(mad_frame_decode(&Frame,&Stream)) {
            if(MAD_RECOVERABLE(Stream.error)) {
                fprintf(stderr,"recoverable frame level error\n");
                fflush(stderr);
                continue;
            } else {
                if(Stream.error==MAD_ERROR_BUFLEN) {
                    continue;
                } else {
                    fprintf(stderr,"unrecoverable frame level error\n");
                    Status=1;
                    break;
                }
            }
        }

        FrameCount++;
        mad_timer_add(&Timer,Frame.header.duration);
        
        mad_synth_frame(&Synth,&Frame);

        for(i=0;i<Synth.pcm.length;i++) {
            unsigned short  Sample;
            
            /* Left channel */
            Sample=scale(Synth.pcm.samples[0][i],&d0);
            *(OutputPtr++)=Sample&0xff;
            *(OutputPtr++)=Sample>>8;
            
            /* Right channel. If the decoded stream is monophonic then
             * the right output channel is the same as the left one.
             */
            if(MAD_NCHANNELS(&Frame.header)==2) {
                Sample=scale(Synth.pcm.samples[1][i],&d1);
            }

            *(OutputPtr++)=Sample&0xff;
            *(OutputPtr++)=Sample>>8;
            
            /* Flush the buffer if it is full. */
            if (OutputPtr==OutputBufferEnd) {
                if (output_sound(&sound, OutputBuffer,
                                 OUTPUT_BUFFER_SIZE)!=OUTPUT_BUFFER_SIZE) {
                    fprintf(stderr,"PCM write error.\n");
                    Status=2;
                    break;
                }
                OutputPtr=OutputBuffer;
            }
            }

        if ((key=button_get(0))==BUTTON_STOP)
	{
            break; 
	}

    }while(1);
    
    /* Mad is no longer used, the structures that were initialized must
     * now be cleared.
     */
    mad_synth_finish(&Synth);
    mad_frame_finish(&Frame);
    mad_stream_finish(&Stream);

    /* If the output buffer is not empty and no error occured during
     * the last write, then flush it. */
    if(OutputPtr!=OutputBuffer && Status!=2)
        {
            size_t  BufferSize=OutputPtr-OutputBuffer;

            if (output_sound(&sound, OutputPtr, BufferSize)!=(int)BufferSize)
                {
                    fprintf(stderr,"PCM write error\n");
                    Status=2;
                }
        }

    /* Accounting report if no error occured. */
    if(!Status)
        {
            char  Buffer[80];

            mad_timer_string(Timer,Buffer,"%lu:%02lu.%03u",
                             MAD_UNITS_MINUTES,MAD_UNITS_MILLISECONDS,0);
            fprintf(stderr,"%lu frames decoded (%s).\n",FrameCount,Buffer);
        }

    close_sound(&sound);
    /* That's the end of the world (in the H. G. Wells way). */
    return;
}
Exemple #14
0
static int mp3_startread(snd_stream_t *stream)
{
	mp3_priv_t *p = (mp3_priv_t *) stream->priv;
	size_t ReadSize;

	mad_stream_init(&p->Stream);
	mad_frame_init(&p->Frame);
	mad_synth_init(&p->Synth);
	mad_timer_reset(&p->Timer);

	/* Decode at least one valid frame to find out the input
	 * format.  The decoded frame will be saved off so that it
	 * can be processed later.
	 */
	ReadSize = FS_fread(p->mp3_buffer, 1, MP3_BUFFER_SIZE, &stream->fh);
	if (!ReadSize || FS_ferror(&stream->fh))
		return -1;

	mad_stream_buffer(&p->Stream, p->mp3_buffer, ReadSize);

	/* Find a valid frame before starting up.  This makes sure
	 * that we have a valid MP3 and also skips past ID3v2 tags
	 * at the beginning of the audio file.
	 */
	p->Stream.error = MAD_ERROR_NONE;
	while (mad_frame_decode(&p->Frame,&p->Stream))
	{
		/* check whether input buffer needs a refill */
		if (p->Stream.error == MAD_ERROR_BUFLEN)
		{
			if (mp3_inputdata(stream) == -1)
				return -1;/* EOF with no valid data */

			continue;
		}

		/* Consume any ID3 tags */
		mp3_inputtag(stream);

		/* FIXME: We should probably detect when we've read
		 * a bunch of non-ID3 data and still haven't found a
		 * frame.  In that case we can abort early without
		 * scanning the whole file.
		 */
		p->Stream.error = MAD_ERROR_NONE;
	}

	if (p->Stream.error)
	{
		Con_Printf("MP3: No valid MP3 frame found\n");
		return -1;
	}

	switch(p->Frame.header.mode)
	{
	case MAD_MODE_SINGLE_CHANNEL:
	case MAD_MODE_DUAL_CHANNEL:
	case MAD_MODE_JOINT_STEREO:
	case MAD_MODE_STEREO:
		stream->info.channels = MAD_NCHANNELS(&p->Frame.header);
		break;
	default:
		Con_Printf("MP3: Cannot determine number of channels\n");
		return -1;
	}

	p->FrameCount = 1;

	mad_timer_add(&p->Timer,p->Frame.header.duration);
	mad_synth_frame(&p->Synth,&p->Frame);
	stream->info.rate = p->Synth.pcm.samplerate;
	stream->info.bits = MP3_MAD_SAMPLEBITS;
	stream->info.width = MP3_MAD_SAMPLEWIDTH;

	p->cursamp = 0;

	return 0;
}
Exemple #15
0
static int mad_frame_seek(input_object *obj, int frame)
{
	struct mad_local_data *data;
	struct mad_header header;
	int skip;
	ssize_t byte_offset;

	if (!obj)
		return 0;
	data = (struct mad_local_data *)obj->local_data;

	if (!data || !data->seekable)
		return 0;

	//alsaplayer_error("frame_seek(..., %d)", frame);
	mad_header_init(&header);

	data->bytes_avail = 0;
	if (frame <= data->highest_frame) {
		skip = 0;

		if (frame > 4) {
			skip = 3;
		}
		byte_offset = data->frames[frame-skip];

		/* Prepare the buffer for a read */
		fill_buffer(data, byte_offset);
		mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
		skip++;
		while (skip != 0) {
			skip--;

			mad_frame_decode(&data->frame, &data->stream);
			if (skip == 0)
				mad_synth_frame (&data->synth, &data->frame);
		}
		data->bytes_avail = data->stream.bufend - 
			data->stream.next_frame;
		data->current_frame = frame;
		data->seeking = 0;
		return data->current_frame;
	}

	data->seeking = 1;
	fill_buffer(data, data->frames[data->highest_frame]);
	mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
	while (data->highest_frame < frame) {
		if (data->bytes_avail < 3072) {
			fill_buffer(data, data->map_offset + MAD_BUFSIZE - data->bytes_avail);
			mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
		}	
		if (mad_header_decode(&header, &data->stream) == -1) {
			if (!MAD_RECOVERABLE(data->stream.error)) {
				fill_buffer(data, 0);
				mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
				data->seeking = 0;
				return 0;
			}				
		}
		data->frames[++data->highest_frame] =
			data->map_offset + data->stream.this_frame - data->mad_map;
		data->bytes_avail = data->stream.bufend - data->stream.next_frame;
	}

	data->current_frame = data->highest_frame;
	if (data->current_frame > 4) {
		skip = 3;
		fill_buffer(data, data->frames[data->current_frame-skip]);
		mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
		skip++;
		while (skip != 0) { 
			skip--;
			mad_frame_decode(&data->frame, &data->stream);
			if (skip == 0) 
				mad_synth_frame (&data->synth, &data->frame);
			data->bytes_avail = data->stream.bufend -
				data->stream.next_frame;
		}
	}

	data->seeking = 0;
	return data->current_frame;

	return 0;
}
Exemple #16
0
/* Read up to len samples from p->Synth
 * If needed, read some more MP3 data, decode them and synth them
 * Place in buf[].
 * Return number of samples read.  */
static int mp3_decode(snd_stream_t *stream, byte *buf, int len)
{
	mp3_priv_t *p = (mp3_priv_t *) stream->priv;
	int donow, i, done = 0;
	mad_fixed_t sample;
	int chan, x;

	do
	{
		x = (p->Synth.pcm.length - p->cursamp) * stream->info.channels;
		donow = q_min(len, x);
		i = 0;
		while (i < donow)
		{
			for (chan = 0; chan < stream->info.channels; chan++)
			{
				sample = p->Synth.pcm.samples[chan][p->cursamp];
				/* convert from fixed to short,
				 * write in host-endian format. */
				if (sample <= -MAD_F_ONE)
					sample = -0x7FFF;
				else if (sample >= MAD_F_ONE)
					sample = 0x7FFF;
				else
					sample >>= (MAD_F_FRACBITS + 1 - 16);
				if (host_bigendian)
				{
					*buf++ = (sample >> 8) & 0xFF;
					*buf++ = sample & 0xFF;
				}
				else /* assumed LITTLE_ENDIAN. */
				{
					*buf++ = sample & 0xFF;
					*buf++ = (sample >> 8) & 0xFF;
				}
				i++;
			}
			p->cursamp++;
		}

		len -= donow;
		done += donow;

		if (len == 0)
			break;

		/* check whether input buffer needs a refill */
		if (p->Stream.error == MAD_ERROR_BUFLEN)
		{
			if (mp3_inputdata(stream) == -1)
			{
				/* check feof() ?? */
				Con_DPrintf("mp3 EOF\n");
				break;
			}
		}

		if (mad_frame_decode(&p->Frame, &p->Stream))
		{
			if (MAD_RECOVERABLE(p->Stream.error))
			{
				mp3_inputtag(stream);
				continue;
			}
			else
			{
				if (p->Stream.error == MAD_ERROR_BUFLEN)
					continue;
				else
				{
					Con_Printf("MP3: unrecoverable frame level error (%s)\n",
							mad_stream_errorstr(&p->Stream));
					break;
				}
			}
		}
		p->FrameCount++;
		mad_timer_add(&p->Timer, p->Frame.header.duration);
		mad_synth_frame(&p->Synth, &p->Frame);
		p->cursamp = 0;
	} while (1);
Exemple #17
0
static int mad_play_frame(input_object *obj, char *buf)
{
	struct mad_local_data *data;
	struct mad_pcm *pcm;
	mad_fixed_t const *left_ch;
	mad_fixed_t const *right_ch;
	int16_t	*output;
	int nsamples;
	int nchannels;

	if (!obj)
		return 0;
	data = (struct mad_local_data *)obj->local_data;
	if (!data)
		return 0;
	if (data->bytes_avail < 3072) {
		/*
		   alsaplayer_error("Filling buffer = %d,%d",
		   data->bytes_avail,
		   data->map_offset + MAD_BUFSIZE - data->bytes_avail);
		   */
		fill_buffer(data, -1); /* data->map_offset + MAD_BUFSIZE - data->bytes_avail); */
		mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
	} else {
		/* alsaplayer_error("bytes_avail = %d", data->bytes_avail); */
	}
	if (mad_frame_decode(&data->frame, &data->stream) == -1) {
		if (!MAD_RECOVERABLE(data->stream.error)) {
			/*
			   alsaplayer_error("MAD error: %s (%d). fatal", 
			   error_str(data->stream.error, data->str),
			   data->bytes_avail);
			   */	
			mad_frame_mute(&data->frame);
			return 0;
		} else {
			if (reader_eof(data->mad_fd)) {
				return 0;
			}	
			//alsaplayer_error("MAD error: %s (not fatal)", error_str(data->stream.error, data->str)); 
			memset(buf, 0, obj->frame_size);
			return 1;
		}
	}
	data->current_frame++;
	if (data->seekable && data->current_frame < (obj->nr_frames + FRAME_RESERVE)) {
		data->frames[data->current_frame] = 
			data->map_offset + data->stream.this_frame - data->mad_map;
		if (data->current_frame > 3 && 
				(data->frames[data->current_frame] -
				 data->frames[data->current_frame-3]) < 6) {
			return 0;
		}		
		if (data->highest_frame < data->current_frame)
			data->highest_frame = data->current_frame;
	}				

	mad_synth_frame (&data->synth, &data->frame);

	{
		pcm = &data->synth.pcm;
		output = (int16_t *)buf;
		nsamples = pcm->length;
		nchannels = pcm->channels;
		if (nchannels != obj->nr_channels) {
			alsaplayer_error("ERROR: bad data stream! (channels: %d != %d, frame %d)",
					nchannels, 
					obj->nr_channels,
					data->current_frame);
			mad_frame_mute(&data->frame);
			memset(buf, 0, obj->frame_size);
			return 1;
		}	
		obj->nr_channels = nchannels;
		if (data->samplerate != data->frame.header.samplerate) {
			alsaplayer_error("ERROR: bad data stream! (samplerate: %d != %d, frame %d)",
					data->samplerate, 
					data->frame.header.samplerate,
					data->current_frame);
			mad_frame_mute(&data->frame);
			memset(buf, 0, obj->frame_size);
			return 1;
		}	
		data->samplerate = data->frame.header.samplerate;
		left_ch = pcm->samples[0];
		right_ch = pcm->samples[1];
		while (nsamples--) {
			*output++ = my_scale(*(left_ch++));
			if (nchannels == 1) {
				*output++ = my_scale(*(left_ch-1));
			} else { /* nchannels == 2 */
				*output++ = my_scale(*(right_ch++));
			}	

		}
	}
	data->bytes_avail = data->stream.bufend - data->stream.next_frame;
	return 1;
}
Exemple #18
0
static void mp_render_ex (void *dest, unsigned nsamp)
{
  short *sout = (short *) dest;

  int localerrors = 0;

  if (!mp_playing || mp_paused)
  {
    memset (dest, 0, nsamp * 4);
    return;
  }

  while (1)
  {
    // write any leftover data from last MP3 frame
    while (mp_leftoversamps > 0 && nsamp > 0)
    {
      short s = mp_fixtoshort (Synth.pcm.samples[0][mp_leftoversamppos]);
      *sout++ = s;
      if (Synth.pcm.channels == 2)
        s = mp_fixtoshort (Synth.pcm.samples[1][mp_leftoversamppos]);
      // if mono, just duplicate the first channel again
      *sout++ = s;

      mp_leftoversamps -= 1;
      mp_leftoversamppos += 1;
      nsamp -= 1;
    }
    if (nsamp == 0)
      return; // done
    
    // decode next valid MP3 frame
    while (mad_frame_decode (&Frame, &Stream) != 0)
    {
      if (MAD_RECOVERABLE (Stream.error))
      { // unspecified problem with one frame.
        // try the next frame, but bail if we get a bunch of crap in a row;
        // likely indicates a larger problem (and if we don't bail, we could
        // spend arbitrarily long amounts of time looking for the next good
        // packet)
        localerrors++;
        if (localerrors == 10)
        {
          lprintf (LO_WARN, "mad_frame_decode: Lots of errors.  Most recent %s\n", mad_stream_errorstr (&Stream));
          mp_playing = 0;
          memset (sout, 0, nsamp * 4);
          return;
        }
      }  
      else if (Stream.error == MAD_ERROR_BUFLEN)
      { // EOF
        // FIXME: in order to not drop the last frame, there must be at least MAD_BUFFER_GUARD
        // of extra bytes (with value 0) at the end of the file.  current implementation
        // drops last frame
        if (mp_looping)
        { // rewind, then go again
          mad_stream_buffer (&Stream, mp_data, mp_len);
          continue;
        }
        else
        { // stop
          mp_playing = 0;
          memset (sout, 0, nsamp * 4);
          return;
        }
      }
      else
      { // oh well.
        lprintf (LO_WARN, "mad_frame_decode: Unrecoverable error %s\n", mad_stream_errorstr (&Stream));
        mp_playing = 0;
        memset (sout, 0, nsamp * 4);
        return;
      }
    }

    // got a good frame, so synth it and dispatch it.
    mad_synth_frame (&Synth, &Frame);
    mp_leftoversamps = Synth.pcm.length;
    mp_leftoversamppos = 0;

  }
  // NOT REACHED
}
Exemple #19
0
static int mad_open(input_object *obj, const char *path)
{
	struct mad_local_data *data;
	char *p;
	int mode;

	if (!obj)
		return 0;

	obj->local_data = malloc(sizeof(struct mad_local_data));
	if (!obj->local_data) {
		puts("failed to allocate local data");
		return 0;
	}
	data = (struct mad_local_data *)obj->local_data;
	memset(data, 0, sizeof(struct mad_local_data));

	if ((data->mad_fd = reader_open(path, &reader_status, obj)) == NULL) {
		fprintf(stderr, "mad_open(obj, %s) failed\n", path);
		free(obj->local_data);
		obj->local_data = NULL;
		return 0;
	}
	obj->flags = 0;

	if (strncasecmp(path, "http://", 7) == 0) {
		obj->flags |= P_STREAMBASED;
		strcpy(data->sinfo.status, "Prebuffering");
	} else {
		obj->flags |= P_FILEBASED;
	}
	if (!reader_seekable(data->mad_fd)) {
		data->seekable = 0;
	} else {
		obj->flags |= P_SEEK;
		obj->flags |= P_PERFECTSEEK;
		data->seekable = 1;
	}
	obj->flags |= P_REENTRANT;

	mad_init_decoder(data);
	memset(&data->xing, 0, sizeof(struct xing));
	xing_init (&data->xing);
	data->mad_init = 1;
	fill_buffer(data, -1);
	//alsaplayer_error("initial bytes_avail = %d", data->bytes_avail);
	if (obj->flags & P_PERFECTSEEK) {
		data->offset = find_initial_frame(data->mad_map, 
				data->bytes_avail < STREAM_BUFFER_SIZE ? data->bytes_avail :
				STREAM_BUFFER_SIZE);
	} else {
		data->offset = 0;
	}	
	data->highest_frame = 0;
	if (data->offset < 0) {
		//fprintf(stderr, "mad_open() couldn't find valid MPEG header\n");
		data->offset = 0;
	}
	//alsaplayer_error("data->offset = %d", data->offset);
	if (data->offset > data->bytes_avail) {
		data->seekable = 1;
		//alsaplayer_error("Need to refill buffer (data->offset = %d)", data->offset);
		fill_buffer(data, 0);
		mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
	} else {
		mad_stream_buffer(&data->stream, data->mad_map + data->offset,
				data->bytes_avail - data->offset);
		data->bytes_avail -= data->offset;
	}	
first_frame:

	if ((mad_header_decode(&data->frame.header, &data->stream) == -1)) {
		switch (data->stream.error) {
			case MAD_ERROR_BUFLEN:
				return 0;
			case MAD_ERROR_LOSTSYNC:
			case MAD_ERROR_BADEMPHASIS:
			case MAD_ERROR_BADBITRATE:
			case MAD_ERROR_BADLAYER:	
			case MAD_ERROR_BADSAMPLERATE:	
				//alsaplayer_error("Error %x (frame %d)", data->stream.error, data->current_frame);
				data->bytes_avail-=(data->stream.next_frame - data->stream.this_frame);
				goto first_frame;
				break;
			case MAD_ERROR_BADBITALLOC:
				return 0;
			case MAD_ERROR_BADCRC:
				alsaplayer_error("MAD_ERROR_BADCRC: %s", error_str(data->stream.error, data->str));
			case MAD_ERROR_BADBIGVALUES:
			case MAD_ERROR_BADDATAPTR:
				break;
			default:
				alsaplayer_error("ERROR: %s", error_str(data->stream.error, data->str));
				alsaplayer_error("No valid frame found at start (pos: %d, error: 0x%x --> %x %x %x %x) (%s)", data->offset, data->stream.error, 
						data->stream.this_frame[0],
						data->stream.this_frame[1],
						data->stream.this_frame[2],
						data->stream.this_frame[3],path);
				return 0;
		}
	}

	mad_frame_decode(&data->frame, &data->stream);
	/*	
		alsaplayer_error("xing parsing...%x %x %x %x (%x %d)", 
		data->stream.this_frame[0], data->stream.this_frame[1],
		data->stream.this_frame[2], data->stream.this_frame[3],
		data->stream.anc_ptr, data->stream.anc_bitlen);
		*/		
	if (xing_parse(&data->xing, data->stream.anc_ptr, data->stream.anc_bitlen) == 0) {
		// We use the xing data later on
	}

	mode = (data->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ?
		1 : 2;
	data->samplerate = data->frame.header.samplerate;
	data->bitrate	= data->frame.header.bitrate;
	mad_synth_frame (&data->synth, &data->frame);
	{
		struct mad_pcm *pcm = &data->synth.pcm;			

		obj->nr_channels = pcm->channels;
		//alsaplayer_error("nr_channels = %d", obj->nr_channels);
	}
	//alsaplayer_error("Initial: %d, %d, %d", data->samplerate, data->bitrate, obj->nr_channels);
	/* Calculate some values */
	data->bytes_avail = data->stream.bufend - data->stream.next_frame;
	{
		int64_t time;
		int64_t samples;
		int64_t frames;

		long oldpos = reader_tell(data->mad_fd);
		reader_seek(data->mad_fd, 0, SEEK_END);

		data->filesize = reader_tell(data->mad_fd);
		data->filesize -= data->offset;

		reader_seek(data->mad_fd, oldpos, SEEK_SET);
		if (data->bitrate)
			time = (data->filesize * 8) / (data->bitrate);
		else
			time = 0;

		samples = 32 * MAD_NSBSAMPLES(&data->frame.header);

		obj->frame_size = (int) samples << 2; /* Assume 16-bit stereo */
		frames = data->samplerate * (time+1) / samples;
		if (data->xing.flags & XING_FRAMES) {
			obj->nr_frames = data->xing.frames;
		} else {	
			obj->nr_frames = (int) frames;
		}	
		obj->nr_tracks = 1;
	}
	/* Determine if nr_frames makes sense */
	if (!(obj->flags & P_SEEK) && (obj->flags & P_STREAMBASED)) {
		obj->nr_frames = -1;
	}	

	/* Allocate frame index */
	if (!data->seekable  || obj->nr_frames > 1000000 ||
			(data->frames = (ssize_t *)malloc((obj->nr_frames + FRAME_RESERVE) * sizeof(ssize_t))) == NULL) {
		data->seekable = 0; // Given really
	}	else {
		data->seekable = 1;
		data->frames[0] = 0;
	}	
	data->mad_init = 1;

	p = strrchr(path, '/');
	if (p) {
		strcpy(data->filename, ++p);
	} else {
		strcpy(data->filename, path);
	}
	strcpy(data->path, path);

	data->parse_id3 = prefs_get_bool(ap_prefs, "mad", "parse_id3", 1);

	return 1;
}
Exemple #20
0
bool CMpegAudioDecoder::DecodeFrame(const BYTE *pData, DWORD *pDataSize, DecodeFrameInfo *pInfo)
{
	if (!m_bInitialized) {
		return false;
	}

	if (m_MadStream.buffer == nullptr || m_MadStream.error == MAD_ERROR_BUFLEN) {
		size_t ReadSize, Remain;

		if (m_MadStream.next_frame != nullptr) {
			Remain = m_MadStream.bufend - m_MadStream.next_frame;
			::MoveMemory(m_InputBuffer, m_MadStream.next_frame, Remain);
			ReadSize = INPUT_BUFFER_SIZE - Remain;
		} else {
			ReadSize = INPUT_BUFFER_SIZE;
			Remain = 0;
		}

		if (ReadSize > *pDataSize)
			ReadSize = *pDataSize;
		*pDataSize = (DWORD)ReadSize;

		::CopyMemory(&m_InputBuffer[Remain], pData, ReadSize);

		mad_stream_buffer(&m_MadStream, m_InputBuffer, (unsigned long)(ReadSize + Remain));
		m_MadStream.error = MAD_ERROR_NONE;
	} else {
		*pDataSize = 0;
	}

	if (mad_frame_decode(&m_MadFrame, &m_MadStream)) {
		pInfo->Samples = 0;

		if (m_MadStream.error == MAD_ERROR_BUFLEN)
			return true;
		if (MAD_RECOVERABLE(m_MadStream.error))
			return true;
#ifdef _DEBUG
		::OutputDebugStringA("libmad error : ");
		::OutputDebugStringA(mad_stream_errorstr(&m_MadStream));
		::OutputDebugStringA("\n");
#endif
		ResetDecoder();
		return false;
	}

	mad_synth_frame(&m_MadSynth, &m_MadFrame);

	const BYTE Channels = MAD_NCHANNELS(&m_MadFrame.header);
	short *p = m_PcmBuffer;

	if (Channels == 1) {
		for (int i = 0; i < m_MadSynth.pcm.length; i++) {
			*p++ = FixedToInt16(m_MadSynth.pcm.samples[0][i]);
		}
	} else {
		for (int i = 0; i < m_MadSynth.pcm.length; i++) {
			*p++ = FixedToInt16(m_MadSynth.pcm.samples[0][i]);
			*p++ = FixedToInt16(m_MadSynth.pcm.samples[1][i]);
		}
	}

	m_AudioInfo.Frequency = m_MadSynth.pcm.samplerate;
	m_AudioInfo.Channels = Channels;
	m_AudioInfo.OrigChannels = Channels;
	m_AudioInfo.bDualMono = false;

	pInfo->pData = (const BYTE*)m_PcmBuffer;
	pInfo->Samples = m_MadSynth.pcm.length;
	pInfo->Info = m_AudioInfo;
	pInfo->bDiscontinuity = m_bDecodeError;

	return true;
}
int Mp3Decoder::decode_frame(sh_audio_t *sh,unsigned char *outdata,int *outlen){
    mad_decoder_t *mad_dec = (mad_decoder_t *) sh->context;
    int len;
	unsigned char *inbuf = buffer;
	int inbuff_len = a_in_buffer_len;
	*outlen = 0;
	uint16_t *output = (uint16_t *)outdata; 
	int nChannels = 0;
	while(1){
		int ret;
//		EL("sh->a_in_buffer: %p, inbuff_len: %d",inbuf,inbuff_len);
		mad_dec->stream.error = MAD_ERROR_NONE;
		mad_stream_buffer (&mad_dec->stream, (unsigned char *)inbuf, inbuff_len);
//		EL("");
		ret=mad_frame_decode (&mad_dec->frame, &mad_dec->stream);
        	if (sh->samplerate == 0)//hpwang 2011-08-03 add for samplerate is zero while mpeg2 audio
		  sh->samplerate = mad_dec->frame.header.samplerate;
		nChannels = mad_dec->frame.header.mode ? 2 : 1;
		if (nChannels != sh->channels)
		  sh->channels = mad_dec->synth.pcm.channels;
//		ALOGE("RET: %d, stream error: %d",ret,mad_dec->stream.error);
//		EL("ret: %d, next_frame: %p",ret,mad_dec->stream.next_frame);

		//ALOGE("sh->channels = %d,sh->samplerate = %d",sh->channels,sh->samplerate);
		inbuff_len -= (mad_dec->stream.next_frame - inbuf); 
		inbuf = (unsigned char *)mad_dec->stream.next_frame;
		if(inbuff_len <= 0)
		{
			a_in_buffer_len = 0;
			return 0;
		}
		a_in_buffer_len = inbuff_len;
		if(a_in_buffer_len == 0)
			return (inbuf - buffer);

		if (ret == 0){
			mad_synth_frame (&mad_dec->synth, &mad_dec->frame);
			{
				unsigned int         nchannels, nsamples;
				mad_fixed_t const   *left_ch, *right_ch;
				struct mad_pcm      *pcm = &mad_dec->synth.pcm;
				
				nchannels = pcm->channels;
				nsamples  = pcm->length;
				left_ch   = pcm->samples[0];
				right_ch  = pcm->samples[1];
				*outlen += nchannels*nsamples;
				
				while (nsamples--) {
					/* output sample(s) in 16-bit signed little-endian PCM */
					*output++ = scale(*left_ch++);
					if (nchannels == 2)
						*output++ = scale(*right_ch++);
						
				}
			}
		}else if(!MAD_RECOVERABLE(mad_dec->stream.error))
		{
			if(mad_dec->stream.error == MAD_ERROR_BUFLEN)
			{
				memcpy(buffer, inbuf, a_in_buffer_len);
				return (inbuf - buffer);
			}
			else
			{
				//memcpy(buffer, inbuf, a_in_buffer_len);
				return 0;
			}
		}
	}
    mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Cannot sync MAD frame\n");
    return 0;
}
Exemple #22
0
static
int run_sync(struct mad_decoder *decoder)
{
  enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
  void *error_data;
  int bad_last_frame = 0;
  struct mad_stream *stream;
  struct mad_frame *frame;
  struct mad_synth *synth;
  int result = 0;

  if (decoder->input_func == 0)
    return 0;

  if (decoder->error_func) {
    error_func = decoder->error_func;
    error_data = decoder->cb_data;
  }
  else {
    error_func = error_default;
    error_data = &bad_last_frame;
  }

#ifndef USE_ASYNC
  stream = &decoder->sync.stream;
  frame  = &decoder->sync.frame;
  synth  = &decoder->sync.synth;
  memset(&decoder->sync, 0, sizeof(decoder->sync));
#endif

  mad_stream_init(stream);
  mad_frame_init(frame);
  mad_synth_init(synth);

  mad_stream_options(stream, decoder->options);

  do {
    switch (decoder->input_func(decoder->cb_data, stream)) {
    case MAD_FLOW_STOP:
      goto done;
    case MAD_FLOW_BREAK:
      goto fail;
    case MAD_FLOW_IGNORE:
      continue;
    case MAD_FLOW_CONTINUE:
      break;
    }

    while (1) {
# if defined(USE_ASYNC)
      if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
	switch (check_message(decoder)) {
	case MAD_FLOW_IGNORE:
	case MAD_FLOW_CONTINUE:
	  break;
	case MAD_FLOW_BREAK:
	  goto fail;
	case MAD_FLOW_STOP:
	  goto done;
	}
      }
# endif

      if (decoder->header_func) {
	if (mad_header_decode(&frame->header, stream) == -1) {
	  if (!MAD_RECOVERABLE(stream->error))
	    break;

	  switch (error_func(error_data, stream, frame)) {
	  case MAD_FLOW_STOP:
	    goto done;
	  case MAD_FLOW_BREAK:
	    goto fail;
	  case MAD_FLOW_IGNORE:
	  case MAD_FLOW_CONTINUE:
	  default:
	    continue;
	  }
	}

	switch (decoder->header_func(decoder->cb_data, &frame->header)) {
	case MAD_FLOW_STOP:
	  goto done;
	case MAD_FLOW_BREAK:
	  goto fail;
	case MAD_FLOW_IGNORE:
	  continue;
	case MAD_FLOW_CONTINUE:
	  break;
	}
      }

      if (mad_frame_decode(frame, stream) == -1) {
	if (!MAD_RECOVERABLE(stream->error))
	  break;

	switch (error_func(error_data, stream, frame)) {
	case MAD_FLOW_STOP:
	  goto done;
	case MAD_FLOW_BREAK:
	  goto fail;
	case MAD_FLOW_IGNORE:
	  break;
	case MAD_FLOW_CONTINUE:
	default:
	  continue;
	}
      }
      else
	bad_last_frame = 0;

      if (decoder->filter_func) {
	switch (decoder->filter_func(decoder->cb_data, stream, frame)) {
	case MAD_FLOW_STOP:
	  goto done;
	case MAD_FLOW_BREAK:
	  goto fail;
	case MAD_FLOW_IGNORE:
	  continue;
	case MAD_FLOW_CONTINUE:
	  break;
	}
      }

      mad_synth_frame(synth, frame);

      if (decoder->output_func) {
	switch (decoder->output_func(decoder->cb_data,
				     &frame->header, &synth->pcm)) {
	case MAD_FLOW_STOP:
	  goto done;
	case MAD_FLOW_BREAK:
	  goto fail;
	case MAD_FLOW_IGNORE:
	case MAD_FLOW_CONTINUE:
	  break;
	}
      }
    }
  }
  while (stream->error == MAD_ERROR_BUFLEN);

 fail:
  result = -1;

 done:
  mad_synth_finish(synth);
  mad_frame_finish(frame);
  mad_stream_finish(stream);

  return result;
}
Exemple #23
0
madx_sig madx_read (	unsigned char *in_buffer, 
	unsigned char *out_buffer, madx_house *mxhouse, madx_stat *mxstat)
{


	// "Random" seed for generating dither. Used 
	// by scale_audio() in preparing the samples 
	// for 16 bit output. 

	mad_fixed_t 	rnscale = 0xa8b9ff7e;

	unsigned char	*guard_ptr  = NULL;
	unsigned char	*readstart;

	// Clear mxstat->msg
	sprintf(mxstat->msg,"");
	


	mxstat->buffstart = 0;


	// Input file has been read completely
	if ( mxstat->is_eof && !mxstat->readsize )
	{

		sprintf(mxstat->msg,"End of input stream"); 
		return(EOF_REACHED); 
	}

	
	
	// Executes on initial loop

	if ( 	(mxstat->readsize == 0)  && 
			(mxstat->remaining == 0) &&
			mxhouse->stream.buffer == NULL 	)
	{

			mxstat->readsize = MADX_INPUT_BUFFER_SIZE;
			mxstat->remaining = 0;
			return(MORE_INPUT);
	}


	readstart = in_buffer;
	



	// Stream buffer

	if ( mxhouse->stream.buffer == NULL ||
			mxhouse->stream.error == MAD_ERROR_BUFLEN )
	{


		// BUFFER_GUARD
		// "mxstat->is_eof" must be set to
		// non-zero IMMEDIATELY (see "test.cpp")
		// once it is detected, so the following
		// may execute, padding the buffer.

		if( mxstat->is_eof )
		{
		
			guard_ptr = in_buffer + mxstat->readsize;
			memset( guard_ptr, 0, MAD_BUFFER_GUARD );
		
			mxstat->readsize += MAD_BUFFER_GUARD;
		}



		// Pipe the new buffer content to libmad's 
		// stream decoder facility.

		mad_stream_buffer( &mxhouse->stream, 
				in_buffer, mxstat->readsize + mxstat->remaining );
		
		mxhouse->stream.error = (mad_error)0;

	}




	


	// [Madlld comment]:
	// Decode the next MPEG frame. The streams is read from the
	// buffer, its constituents are broken down and stored in the 
	// mxhouse->frame structure, ready for examination/alteration 
	// or PCM synthesis. Decoding options are carried in the Frame
	// structure from the mxhouse->stream structure.
	// 
	// Error handling: mad_frame_decode() returns a non zero value
	// when an error occurs. The error condition can be checked in
	// the error member of the mxhouse->stream structure. A mad error is
	// recoverable or fatal, the error status is checked with the
	// MAD_RECOVERABLE macro.
	// 
	// {4} When a fatal error is encountered all decoding
	// activities shall be stopped, except when a MAD_ERROR_BUFLEN
	// is signaled. This condition means that the
	// mad_frame_decode() function needs more input to complete
	// its work. One shall refill the buffer and repeat the
	// mad_frame_decode() call. Some bytes may be left unused at
	// the end of the buffer if those bytes forms an incomplete
	// frame. Before refilling, the remaining bytes must be moved
	// to the beginning of the buffer and used for input for the
	// next mad_frame_decode() invocation. (See the comments
	// marked {2} earlier for more details.)
	// 
	// Recoverable errors are caused by malformed bit-streams, in
	// this case one can call again mad_frame_decode() in order to
	// skip the faulty part and re-sync to the next frame.


	
	if( mad_frame_decode(&mxhouse->frame, &mxhouse->stream) )
	{

		if( MAD_RECOVERABLE(mxhouse->stream.error) )
		{
			

			// Do not print a message if the error is 
			// a loss of synchronization or this loss 
			// is due to the end of stream guard bytes. 

			if( mxhouse->stream.error != MAD_ERROR_LOSTSYNC
				   	||
				mxhouse->stream.this_frame != guard_ptr 
					||
				// Suppress error if caused by ID3 tag.
			   (mxhouse->stream.this_frame[0] != 'I' &&		// ID3v2
				mxhouse->stream.this_frame[1] != 'D' &&
				mxhouse->stream.this_frame[2] != '3') 
			   		||					
			   (mxhouse->stream.this_frame[0] != 'T' &&		// ID3v1
				mxhouse->stream.this_frame[1] != 'A' &&
				mxhouse->stream.this_frame[2] != 'G') )
			{			
				sprintf(mxstat->msg,"Recoverable frame level error (%s)",
						MadErrorString(&mxhouse->stream));

			}	
			return(CALL_AGAIN); 


		}
		else		// Non-recoverable error
		{


			// MAD_ERROR_BUFLEN means that more input
			// is needed (it's not recoverable without
			// interaction from the calling code). The
			// bytes already in the buffer must be 
			// preserved. "mxstat->buffstart" is used
			// to point to the end of the preserved
			// bytes in "in_buffer", then MORE_INPUT 
			// is requested. "mxstat->buffstart" is set
			// to 0 every time "madx_read()" is 
			// called. The calling code checks this 
			// variable to determine if a full buffer 
			// read or a partial read is necessary.
			// (Not "0" signifies a partial read.)

			if( mxhouse->stream.error == MAD_ERROR_BUFLEN )
			{		
				
				
				sprintf(mxstat->msg,
					"Need more input (%s)",	MadErrorString(&mxhouse->stream));
				
				mxstat->remaining = 
					mxhouse->stream.bufend - mxhouse->stream.next_frame;
				
				memmove(in_buffer, 
						mxhouse->stream.next_frame, mxstat->remaining);
				
				mxstat->readsize = MADX_INPUT_BUFFER_SIZE - mxstat->remaining;


				// How far "forward" in_buffer to begin:
				mxstat->buffstart = in_buffer + mxstat->remaining;
			

				return(MORE_INPUT);			

			}
			else			// Error returned
			{
				sprintf(mxstat->msg,"Unrecoverable frame level error (%s).",
						MadErrorString(&mxhouse->stream));
				return(ERROR_OCCURED); 
			}
		}
	}







	// [Madlld comment]:
	// Accounting. The computed frame duration is in the frame
	// header structure. It is expressed as a fixed point number
	// whole data type is mad_timer_t. It is different from the
	// samples fixed point format and unlike it, it can't directly
	// be added or subtracted. The timer module provides several
	// functions to operate on such numbers. Be careful there, as
	// some functions of libmad's timer module receive some of
	// their mad_timer_t arguments by value!

	mxhouse->frame_cnt++;
	mad_timer_add( &mxhouse->timer, mxhouse->frame.header.duration );




	// Once decoded the frame is synthesized to 
	// PCM samples. No errors are reported by 
	// mad_synth_frame();

	mad_synth_frame( &mxhouse->synth, &mxhouse->frame );




	
	
	// [Madlld comment]:
	// Synthesized samples must be converted from libmad's fixed
	// point number to the consumer format. Here we use unsigned
	// 16 bit big endian integers on two channels. Integer samples
	// are temporarily stored in a buffer that is flushed when
	// full.
	//
	// Note: Code to computer "big-endian" has been preserved
	// below. It is simply commented out. This source produces
	// 16-bit "little-endian" PCM samples.

	
	for( int i=0; i < mxhouse->synth.pcm.length; i++ )
	{
		signed short	sample;

		// Left channel
		sample = scale_audio(mxhouse->synth.pcm.samples[0][i], &rnscale);

		
		// Originally big-endian:
		// *(mxhouse->output_ptr++)=sample>>8;      
		// *(mxhouse->output_ptr++)=sample&0xff;

		
		// 16-bit little-endian
		*(mxhouse->output_ptr++)=((sample>>0) & 0xff);
		*(mxhouse->output_ptr++)=((sample>>8) & 0xff);



		// Right channel. 
		// If the decoded stream is monophonic then 
		// the right output channel is the same as 
		// the left one.

		if(MAD_NCHANNELS(&mxhouse->frame.header)==2)
			sample = scale_audio(mxhouse->synth.pcm.samples[1][i], &rnscale);

		
		// Originally big-endian:
		// *(mxhouse->output_ptr++)=sample>>8;      
		// *(mxhouse->output_ptr++)=sample&0xff;


		// 16-bit little-endian
		*(mxhouse->output_ptr++)=((sample>>0) & 0xff);			
		*(mxhouse->output_ptr++)=((sample>>8) & 0xff);

	}
		

	// Tell calling code buffer size
	mxstat->write_size = mxhouse->output_ptr - out_buffer;


	// Indicate that buffer is ready to be
	// written.

	if (mxhouse->synth.pcm.length < 1152 
			||	
		MADX_OUTPUT_BUFFER_SIZE - mxstat->write_size  < 1152)
	{

		// Reset pointer
		mxhouse->output_ptr = out_buffer;  
		return(FLUSH_BUFFER);
	}
	else
		return(CALL_AGAIN); 		// Otherwise, continue


}