// Read
//
// Returns number of bytes actually read.
// 
//	Returns -1 if there is nothing more to be read.  This function can return 0, since
// sometimes the amount of bytes requested is too small for the ACM decompression to 
// locate a suitable block
int WaveFile::Read(BYTE *pbDest, UINT cbSize, int service)
{
	unsigned char	*dest_buf=NULL, *uncompressed_wave_data;
	int				rc, uncompressed_bytes_written;
	unsigned int	src_bytes_used, convert_len, num_bytes_desired=0, num_bytes_read;

//	nprintf(("Alan","Reqeusted: %d\n", cbSize));


	if ( service ) {
		uncompressed_wave_data = Wavedata_service_buffer;
	} else {
		uncompressed_wave_data = Wavedata_load_buffer;
	}

	switch ( m_wave_format ) {
		case WAVE_FORMAT_PCM:
			num_bytes_desired = cbSize;
			dest_buf = pbDest;
			break;

		case WAVE_FORMAT_ADPCM:
			if ( !m_hStream_open ) {
				if ( !ACM_stream_open(m_pwfmt_original, &m_wfxDest, (void**)&m_hStream), m_bits_per_sample_uncompressed  ) {
					m_hStream_open = 1;
				} else {
					Int3();
				}
			}

			num_bytes_desired = cbSize;
	
			if ( service ) {
				dest_buf = Compressed_service_buffer;
			} else {
				dest_buf = Compressed_buffer;
			}

			if ( num_bytes_desired <= 0 ) {
				num_bytes_desired = 0;
//				nprintf(("Alan","No bytes required for ADPCM time interval\n"));
			} else {
				num_bytes_desired = ACM_query_source_size((void*)m_hStream, cbSize);
//				nprintf(("Alan","Num bytes desired: %d\n", num_bytes_desired));
			}
			break;

		default:
			nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n"));
			Int3();
			break;

	} // end switch
                
	num_bytes_read = 0;
	convert_len = 0;
	src_bytes_used = 0;

	// read data from disk
	if ( m_data_bytes_left <= 0 ) {
		num_bytes_read = 0;
		uncompressed_bytes_written = 0;
		return -1;
	}

	if ( m_data_bytes_left > 0 && num_bytes_desired > 0 ) {
		int actual_read;

		if ( num_bytes_desired <= (unsigned int)m_data_bytes_left ) {
			num_bytes_read = num_bytes_desired;
		}
		else {
			num_bytes_read = m_data_bytes_left;
		}

		actual_read = mmioRead( cfp, (char *)dest_buf, num_bytes_read );
		if ( (actual_read <= 0) || (m_abort_next_read) ) {
			num_bytes_read = 0;
			uncompressed_bytes_written = 0;
			return -1;
		}

		if ( num_bytes_desired >= (unsigned int)m_data_bytes_left ) {
			m_abort_next_read = 1;			
		}

		num_bytes_read = actual_read;
	}

	// convert data if necessary, to PCM
	if ( m_wave_format == WAVE_FORMAT_ADPCM ) {
		if ( num_bytes_read > 0 ) {
				rc = ACM_convert((void*)m_hStream, dest_buf, num_bytes_read, uncompressed_wave_data, BIGBUF_SIZE, &convert_len, &src_bytes_used);
				if ( rc == -1 ) {
					goto READ_ERROR;
				}
				if ( convert_len == 0 ) {
					Int3();
				}
		}

		Assert(src_bytes_used <= num_bytes_read);
		if ( src_bytes_used < num_bytes_read ) {
			// seek back file pointer to reposition before unused source data
			mmioSeek(cfp, src_bytes_used - num_bytes_read, SEEK_CUR);
		}

		// Adjust number of bytes left
		m_data_bytes_left -= src_bytes_used;
		m_nBytesPlayed += src_bytes_used;
		uncompressed_bytes_written = convert_len;

		// Successful read, keep running total of number of data bytes read
		goto READ_DONE;
	}
	else {
		// Successful read, keep running total of number of data bytes read
		// Adjust number of bytes left
		m_data_bytes_left -= num_bytes_read;
		m_nBytesPlayed += num_bytes_read;
		uncompressed_bytes_written = num_bytes_read;
		goto READ_DONE;
	}
    
READ_ERROR:
	num_bytes_read = 0;
	uncompressed_bytes_written = 0;

READ_DONE:
	m_total_uncompressed_bytes_read += uncompressed_bytes_written;
//	nprintf(("Alan","Read: %d\n", uncompressed_bytes_written));
	return (uncompressed_bytes_written);
}
Beispiel #2
0
// Read
//
// Returns number of bytes actually read.
// 
//	Returns -1 if there is nothing more to be read.  This function can return 0, since
// sometimes the amount of bytes requested is too small for the ACM decompression to 
// locate a suitable block
int WaveFile::Read(BYTE* pbDest, UINT cbSize, int service)
{
	unsigned char* dest_buf = NULL, *uncompressed_wave_data;
	int rc, uncompressed_bytes_written, section, last_section = -1, byte_order = 0;
	unsigned int src_bytes_used, convert_len, num_bytes_desired = 0, num_bytes_read;

	//	nprintf(("Alan","Reqeusted: %d\n", cbSize));

#if BYTE_ORDER == BIG_ENDIAN

	byte_order = 1;

#endif


	if (service)
	{
		uncompressed_wave_data = Wavedata_service_buffer;
	}
	else
	{
		uncompressed_wave_data = Wavedata_load_buffer;
	}

	switch (m_wave_format)
	{
	case WAVE_FORMAT_PCM:
		num_bytes_desired = cbSize;
		dest_buf = pbDest;
		break;

	case WAVE_FORMAT_ADPCM:
		if (!m_hStream_open)
		{
			if (!ACM_stream_open(m_pwfmt_original, &m_wfxDest, (void**)&m_hStream), m_wfmt.wBitsPerSample)
			{
				m_hStream_open = 1;
			}
			else
			{
				Int3();
			}
		}

		num_bytes_desired = cbSize;

		if (service)
		{
			dest_buf = Compressed_service_buffer;
		}
		else
		{
			dest_buf = Compressed_buffer;
		}

		if (num_bytes_desired <= 0)
		{
			num_bytes_desired = 0;
			//				nprintf(("Alan","No bytes required for ADPCM time interval\n"));
		}
		else
		{
			num_bytes_desired = ACM_query_source_size((void*)m_hStream, cbSize);
			//				nprintf(("Alan","Num bytes desired: %d\n", num_bytes_desired));
		}
		break;

	case OGG_FORMAT_VORBIS:
		num_bytes_desired = cbSize;
		dest_buf = pbDest;
		break;

	default:
		nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n"));
		Int3();
		break;

	} // end switch

	num_bytes_read = 0;
	convert_len = 0;
	src_bytes_used = 0;

	// read data from disk
	if (m_data_bytes_left <= 0)
	{
		num_bytes_read = 0;
		uncompressed_bytes_written = 0;
		return -1;
	}

	if ((m_data_bytes_left > 0) && (num_bytes_desired > 0))
	{
		int actual_read = 0;

		if (num_bytes_desired <= (uint)m_data_bytes_left)
		{
			num_bytes_read = num_bytes_desired;
		}
		else
		{
			num_bytes_read = m_data_bytes_left;
		}

		// OGG reading is special
		if (m_wave_format == OGG_FORMAT_VORBIS)
		{
			while (!m_abort_next_read && ((uint)actual_read < num_bytes_read))
			{
				rc = ov_read(&m_snd_info.vorbis_file, (char*)dest_buf + actual_read, num_bytes_read - actual_read,
					byte_order, m_wfmt.wBitsPerSample / 8, 1, &section);

				// fail if the bitstream changes, shouldn't get this far if that's the case though
				if ((last_section != -1) && (last_section != section))
				{
					mprintf(("AUDIOSTR => OGG reading error:  We don't handle bitstream changes!\n"));
					goto READ_ERROR;
				}

				if (rc > 0)
				{
					last_section = section;
					actual_read += rc;
				}
				else if (rc == 0)
				{
					break;
				}
				else if (rc == OV_EBADLINK)
				{
					goto READ_ERROR;
				}
			}
		}
			// standard WAVE reading
		else
		{
			actual_read = mmioRead(m_snd_info.cfp, (char*)dest_buf, num_bytes_read);
		}

		if ((actual_read <= 0) || (m_abort_next_read))
		{
			num_bytes_read = 0;
			uncompressed_bytes_written = 0;
			return -1;
		}

		if (num_bytes_desired >= (uint)m_data_bytes_left)
		{
			m_abort_next_read = 1;
		}

		num_bytes_read = actual_read;
	}

	// convert data if necessary, to PCM
	if (m_wave_format == WAVE_FORMAT_ADPCM)
	{
		if (num_bytes_read > 0)
		{
			rc = ACM_convert((void*)m_hStream, dest_buf, num_bytes_read, uncompressed_wave_data,
				BIGBUF_SIZE, &convert_len, &src_bytes_used);
			if (rc == -1)
			{
				goto READ_ERROR;
			}
			if (convert_len == 0)
			{
				Int3();
			}
		}

		Assert(src_bytes_used <= num_bytes_read);
		if (src_bytes_used < num_bytes_read)
		{
			// seek back file pointer to reposition before unused source data
			mmioSeek(m_snd_info.cfp, src_bytes_used - num_bytes_read, SEEK_CUR);
		}

		// Adjust number of bytes left
		m_data_bytes_left -= src_bytes_used;
		m_nBytesPlayed += src_bytes_used;
		uncompressed_bytes_written = convert_len;

		// Successful read, keep running total of number of data bytes read
		goto READ_DONE;
	}
	else
	{
		// Successful read, keep running total of number of data bytes read
		// Adjust number of bytes left
		m_data_bytes_left -= num_bytes_read;
		m_nBytesPlayed += num_bytes_read;
		uncompressed_bytes_written = num_bytes_read;
		goto READ_DONE;
	}

READ_ERROR:
	num_bytes_read = 0;
	uncompressed_bytes_written = 0;

READ_DONE:
	m_total_uncompressed_bytes_read += uncompressed_bytes_written;
	//	nprintf(("Alan","Read: %d\n", uncompressed_bytes_written));
	return (uncompressed_bytes_written);
}