Пример #1
0
/*
 * NAME:	frame->init()
 * DESCRIPTION:	initialize frame struct
 */
void mad_frame_init(struct mad_frame *frame)
{
  mad_header_init(&frame->header);
  frame->options = 0;
//  frame->overlap = 0;
  mad_frame_mute(frame);
}
Пример #2
0
static struct mp3_data *mp3_open_internal (const char *file,
		const int buffered)
{
	struct mp3_data *data;

	data = (struct mp3_data *)xmalloc (sizeof(struct mp3_data));
	data->ok = 0;
	decoder_error_init (&data->error);

	/* Reset information about the file */
	data->freq = 0;
	data->channels = 0;
	data->skip_frames = 0;
	data->bitrate = -1;
	data->avg_bitrate = -1;

	/* Open the file */
	data->io_stream = io_open (file, buffered);
	if (io_ok(data->io_stream)) {
		data->ok = 1;
		
		data->size = io_file_size (data->io_stream);

		mad_stream_init (&data->stream);
		mad_frame_init (&data->frame);
		mad_synth_init (&data->synth);

		if (options_get_int("Mp3IgnoreCRCErrors"))
				mad_stream_options (&data->stream,
					MAD_OPTION_IGNORECRC);
		
		data->duration = count_time_internal (data);
		mad_frame_mute (&data->frame);
		data->stream.next_frame = NULL;
		data->stream.sync = 0;
		data->stream.error = MAD_ERROR_NONE;

		if (io_seek(data->io_stream, SEEK_SET, 0) == (off_t)-1) {
			decoder_error (&data->error, ERROR_FATAL, 0,
						"seek failed");
			io_close (data->io_stream);
			mad_stream_finish (&data->stream);
			mad_frame_finish (&data->frame);
			mad_synth_finish (&data->synth);
			data->ok = 0;
		}

		data->stream.error = MAD_ERROR_BUFLEN;
	}
	else {
		decoder_error (&data->error, ERROR_FATAL, 0, "Can't open: %s",
				io_strerror(data->io_stream));
		io_close (data->io_stream);
	}

	return data;
}
Пример #3
0
static void
reset_stream_parameters (mp3d_prc_t * ap_prc)
{
  assert (ap_prc);
  mad_frame_mute (&ap_prc->frame_);
  mad_synth_mute (&ap_prc->synth_);
  tiz_mem_set (ap_prc->in_buff_, 0, INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD);
  ap_prc->remaining_ = 0;
  ap_prc->frame_count_ = 0;
  ap_prc->next_synth_sample_ = 0;
  ap_prc->eos_ = false;
}
Пример #4
0
static
enum mad_flow error_default(void *data, struct mad_stream *stream,
                            struct mad_frame *frame) {
    int *bad_last_frame = data;

    switch (stream->error) {
        case MAD_ERROR_BADCRC:
            if (*bad_last_frame)
                mad_frame_mute(frame);
            else
                *bad_last_frame = 1;

            return MAD_FLOW_IGNORE;

        default:
            return MAD_FLOW_CONTINUE;
    }
}
RageSoundReader_MP3::RageSoundReader_MP3()
{
	mad = new madlib_t;
	m_bAccurateSync = false;

	mad_stream_init( &mad->Stream );
	mad_frame_init( &mad->Frame );
	mad_synth_init( &mad->Synth );

	mad_frame_mute( &mad->Frame );
	mad_timer_reset( &mad->Timer );
	mad->length = -1;
	mad->inbuf_filepos = 0;
	mad->header_bytes = 0;
	mad->has_xing = false;
	mad->timer_accurate = 1;
	mad->bitrate = -1;
	mad->first_frame = true;
}
Пример #6
0
SINT SoundSourceMp3::restartDecoding(
        const SeekFrameType& seekFrame) {
    qDebug() << "restartDecoding @" << seekFrame.frameIndex;

    // Discard decoded output
    m_madSynthCount = 0;

    if (getMinFrameIndex() == seekFrame.frameIndex) {
        mad_frame_finish(&m_madFrame);
        mad_synth_finish(&m_madSynth);
    }
    mad_stream_finish(&m_madStream);

    mad_stream_init(&m_madStream);
    mad_stream_options(&m_madStream, MAD_OPTION_IGNORECRC);
    if (getMinFrameIndex() == seekFrame.frameIndex) {
        mad_synth_init(&m_madSynth);
        mad_frame_init(&m_madFrame);
    }

    // Fill input buffer
    mad_stream_buffer(&m_madStream, seekFrame.pInputData,
            m_fileSize - (seekFrame.pInputData - m_pFileData));

    if (getMinFrameIndex() < seekFrame.frameIndex) {
        // Muting is done here to eliminate potential pops/clicks
        // from skipping Rob Leslie explains why here:
        // http://www.mars.org/mailman/public/mad-dev/2001-August/000321.html
        mad_frame_mute(&m_madFrame);
        mad_synth_mute(&m_madSynth);
    }

    if (!decodeFrameHeader(&m_madFrame.header, &m_madStream, false)) {
        if (!isStreamValid(m_madStream)) {
            // Failure -> Seek to EOF
            return getFrameCount();
        }
    }

    return seekFrame.frameIndex;
}
bool RageSoundReader_MP3::MADLIB_rewind()
{
	m_pFile->Seek(0);
			
	mad_frame_mute(&mad->Frame);
	mad_synth_mute(&mad->Synth);
	mad_timer_reset(&mad->Timer);
	mad->outpos = mad->outleft = 0;

	mad_stream_finish(&mad->Stream);
	mad_stream_init(&mad->Stream);
	mad_stream_buffer(&mad->Stream, NULL, 0);
	mad->inbuf_filepos = 0;

	/* Be careful.  We need to leave header_bytes alone, so if we try to SetPosition_estimate
	 * immediately after this, we still know the header size.  However, we need to set first_frame
	 * to true, since the first frame is handled specially in do_mad_frame_decode; if we don't
	 * set it, then we'll be desynced by a frame after an accurate seek. */
//	mad->header_bytes = 0;
	mad->first_frame = true;
	mad->Stream.this_frame = NULL;

	return true;
}
/* Seek to a byte in the file.  If you're going to put the file position
 * back when you're done, and not going to read any data, you don't have
 * to use this. */
int RageSoundReader_MP3::seek_stream_to_byte( int byte )
{
	if( m_pFile->Seek(byte) == -1 )
	{
		SetError( strerror(errno) );
		return 0;
	}

	mad_frame_mute(&mad->Frame);
	mad_synth_mute(&mad->Synth);
	mad_stream_finish(&mad->Stream);
	mad_stream_init(&mad->Stream);

	mad->outleft = mad->outpos = 0;

	mad->inbuf_filepos = byte;

	/* If the position is <= the position of the first audio sample, then
	 * we're at the beginning. */
	if( !mad->tocmap.empty() )
		mad->first_frame = ( byte <= mad->tocmap.begin()->second );

	return 1;
}
/* Handle first-stage decoding: extracting the MP3 frame data. */
int RageSoundReader_MP3::do_mad_frame_decode( bool headers_only )
{
	int bytes_read = 0;

	while(1)
	{
		int ret;

		/* Always actually decode the first packet, so we cleanly parse Xing tags. */
		if( headers_only && !mad->first_frame )
			ret=mad_header_decode( &mad->Frame.header,&mad->Stream );
		else
			ret=mad_frame_decode( &mad->Frame,&mad->Stream );

		if( ret == -1 && (mad->Stream.error == MAD_ERROR_BUFLEN || mad->Stream.error == MAD_ERROR_BUFPTR) )
		{
			if( bytes_read > 25000 )
			{
				/* We've read this much without actually getting a frame; error. */
				SetError( "Can't find data" );
				return -1;
			}

			ret = fill_buffer();
			if( ret <= 0 )
				return ret;
			bytes_read += ret;

			continue;
		}

		if( ret == -1 && mad->Stream.error == MAD_ERROR_LOSTSYNC )
		{
			/* This might be an ID3V2 tag. */
			const int tagsize = id3_tag_query(mad->Stream.this_frame,
				mad->Stream.bufend - mad->Stream.this_frame);

			if( tagsize )
			{
				mad_stream_skip(&mad->Stream, tagsize);

				/* Don't count the tagsize against the max-read-per-call figure. */
				bytes_read -= tagsize;

				continue;
			}
		}

		if( ret == -1 && mad->Stream.error == MAD_ERROR_BADDATAPTR )
		{
			/*
			 * Something's corrupt.  One cause of this is cutting an MP3 in the middle
			 * without reencoding; the first two frames will reference data from previous
			 * frames that have been removed.  The frame is valid--we can get a header from
			 * it, we just can't synth useful data.
			 *
			 * BASS pretends the bad frames are silent.  Emulate that, for compatibility.
			 */
			ret = 0; /* pretend success */
		}

		if( !ret )
		{
			/* OK. */
			if( mad->first_frame )
			{
				/* We're at the beginning.  Is this a Xing tag? */
				if(handle_first_frame())
				{
					/* The first frame contained a header. Continue searching. */
					continue;
				}

				/* We've decoded the first frame of data. 
				 *
				 * We want mad->Timer to represent the timestamp of the first sample of the
				 * currently decoded frame.  Don't increment mad->Timer on the first frame,
				 * or it'll be the time of the *next* frame.  (All frames have the same
				 * duration.) */
				mad->first_frame = false;
				mad->Timer = mad_timer_zero;
				mad->header_bytes = get_this_frame_byte(mad);
			}
			else
			{
				mad_timer_add( &mad->Timer,mad->Frame.header.duration );
			}

			fill_frame_index_cache( mad );

			return 1;
		}

		if( mad->Stream.error == MAD_ERROR_BADCRC )
		{
			/* XXX untested */
			mad_frame_mute(&mad->Frame);
			mad_synth_mute(&mad->Synth);

			continue;
		}

		if( !MAD_RECOVERABLE(mad->Stream.error) )
		{
			/* We've received an unrecoverable error. */
			SetError( mad_stream_errorstr(&mad->Stream) );
			return -1;
		}
	}
}
Пример #10
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;
}