30 Jan 2017

This commit is contained in:
g-cont 2017-01-30 00:00:00 +03:00 committed by Alibek Omarov
parent 537f5cf039
commit a7b6617b6c
6 changed files with 91 additions and 101 deletions

View File

@ -1546,7 +1546,7 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
{
int snd_vol;
if( entnum < 0 ) snd_vol = 128; // bg track or movie track
if( entnum < 0 ) snd_vol = 256; // bg track or movie track
if( snd_vol < 0 ) snd_vol = 0; // fixup negative values
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );

Binary file not shown.

Binary file not shown.

View File

@ -24,37 +24,26 @@ GNU General Public License for more details.
#define MP3_OK 0
#define MP3_NEED_MORE 1
typedef struct mpeg_s
typedef struct
{
void *state; // hidden decoder state
void *file;
int rate; // num samples per second (e.g. 11025 - 11 khz)
int channels; // num channels (1 - mono, 2 - stereo)
int playtime; // stream size in milliseconds
} wavinfo_t;
// custom stdio
long (*fread)( void *handle, void *buf, size_t count );
long (*fseek)( void *handle, long offset, int whence );
void (*close)( void *handle );
// custom stdio
typedef long (*pfread)( void *handle, void *buf, size_t count );
typedef long (*pfseek)( void *handle, long offset, int whence );
// user info
int channels; // num channels
int samples; // per one second
int play_time; // stream size in milliseconds
int rate; // frequency
int outsize; // current data size
char out[8192]; // temporary buffer
size_t streamsize; // size in bytes
char error[256]; // error buffer
} mpeg_t;
// mpg123 exports
extern int create_decoder( mpeg_t *mpg );
extern int feed_mpeg_header( mpeg_t *mpg, const char *data, long bufsize, long streamsize );
extern int feed_mpeg_stream( mpeg_t *mpg, const char *data, long bufsize );
extern int open_mpeg_stream( mpeg_t *mpg, void *file );
extern int read_mpeg_stream( mpeg_t *mpg );
extern int get_stream_pos( mpeg_t *mpg );
extern int set_stream_pos( mpeg_t *mpg, int curpos );
extern void close_decoder( mpeg_t *mpg );
extern void *create_decoder( int *error );
extern int feed_mpeg_header( void *mpg, const char *data, long bufsize, long streamsize, wavinfo_t *sc );
extern int feed_mpeg_stream( void *mpg, const char *data, long bufsize, char *outbuf, size_t *outsize );
extern int open_mpeg_stream( void *mpg, void *file, pfread f_read, pfseek f_seek, wavinfo_t *sc );
extern int read_mpeg_stream( void *mpg, char *outbuf, size_t *outsize );
extern int get_stream_pos( void *mpg );
extern int set_stream_pos( void *mpg, int curpos );
extern void close_decoder( void *mpg );
const char *get_error( void *mpeg );
/*
=================================================================
@ -65,41 +54,50 @@ extern void close_decoder( mpeg_t *mpg );
*/
qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize )
{
mpeg_t mpeg;
void *mpeg;
size_t pos = 0;
size_t bytesWrite = 0;
char out[OUTBUF_SIZE];
size_t outsize;
int ret;
wavinfo_t sc;
// load the file
if( !buffer || filesize < FRAME_SIZE )
return false;
// couldn't create decoder
if( !create_decoder( &mpeg ))
{
MsgDev( D_ERROR, "%s\n", mpeg.error );
if(( mpeg = create_decoder( &ret )) == NULL )
return false;
}
#ifdef _DEBUG
if( ret ) MsgDev( D_ERROR, %s\n", get_error( mpeg ));
#endif
// trying to read header
if( !feed_mpeg_header( &mpeg, buffer, FRAME_SIZE, filesize ))
if( !feed_mpeg_header( mpeg, buffer, FRAME_SIZE, filesize, &sc ))
{
MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted (%s)\n", name, mpeg.error );
close_decoder( &mpeg );
#ifdef _DEBUG
MsgDev( D_ERROR, "Sound_LoadMPG: failed to load (%s): %s\n", name, get_error( mpeg ));
#else
MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", name );
#endif
close_decoder( mpeg );
return false;
}
sound.channels = mpeg.channels;
sound.rate = mpeg.rate;
sound.channels = sc.channels;
sound.rate = sc.rate;
sound.width = 2; // always 16-bit PCM
sound.loopstart = -1;
sound.size = ( sound.channels * sound.rate * sound.width ) * ( mpeg.play_time / 1000 ); // in bytes
sound.size = ( sound.channels * sound.rate * sound.width ) * ( sc.playtime / 1000 ); // in bytes
pos += FRAME_SIZE; // evaluate pos
if( !sound.size )
{
// bad mpeg file ?
MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", name );
close_decoder( &mpeg );
close_decoder( mpeg );
return false;
}
@ -109,9 +107,9 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize )
// decompress mpg into pcm wav format
while( bytesWrite < sound.size )
{
int outsize;
int size;
if( feed_mpeg_stream( &mpeg, NULL, 0 ) != MP3_OK && mpeg.outsize <= 0 )
if( feed_mpeg_stream( mpeg, NULL, 0, out, &outsize ) != MP3_OK && outsize <= 0 )
{
char *data = (char *)buffer + pos;
int bufsize;
@ -122,20 +120,20 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize )
else bufsize = FRAME_SIZE;
pos += bufsize;
if( feed_mpeg_stream( &mpeg, data, bufsize ) != MP3_OK )
if( feed_mpeg_stream( mpeg, data, bufsize, out, &outsize ) != MP3_OK )
break; // there was end of the stream
}
if( bytesWrite + mpeg.outsize > sound.size )
outsize = ( sound.size - bytesWrite );
else outsize = mpeg.outsize;
if( bytesWrite + outsize > sound.size )
size = ( sound.size - bytesWrite );
else size = outsize;
memcpy( &sound.wav[bytesWrite], mpeg.out, outsize );
memcpy( &sound.wav[bytesWrite], out, size );
bytesWrite += outsize;
}
sound.samples = bytesWrite / ( sound.width * sound.channels );
close_decoder( &mpeg );
close_decoder( mpeg );
return true;
}
@ -147,9 +145,11 @@ Stream_OpenMPG
*/
stream_t *Stream_OpenMPG( const char *filename )
{
mpeg_t *mpegFile;
stream_t *stream;
void *mpeg;
file_t *file;
int ret;
wavinfo_t sc;
file = FS_Open( filename, "rb", false );
if( !file ) return NULL;
@ -159,39 +159,38 @@ stream_t *Stream_OpenMPG( const char *filename )
stream->file = file;
stream->pos = 0;
mpegFile = Mem_Alloc( host.soundpool, sizeof( mpeg_t ));
// couldn't create decoder
if( !create_decoder( mpegFile ))
if(( mpeg = create_decoder( &ret )) == NULL )
{
MsgDev( D_ERROR, "Stream_OpenMPG: couldn't create decoder: %s\n", mpegFile->error );
Mem_Free( mpegFile );
MsgDev( D_ERROR, "Stream_OpenMPG: couldn't create decoder\n" );
Mem_Free( stream );
FS_Close( file );
return NULL;
}
mpegFile->fread = FS_Read;
mpegFile->fseek = FS_Seek;
mpegFile->close = FS_Close;
#ifdef _DEBUG
if( ret ) MsgDev( D_ERROR, %s\n", get_error( mpeg ));
#endif
// trying to open stream and read header
if( !open_mpeg_stream( mpegFile, file ))
if( !open_mpeg_stream( mpeg, file, FS_Read, FS_Seek, &sc ))
{
MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted: %s\n", filename, mpegFile->error );
close_decoder( mpegFile );
Mem_Free( mpegFile );
#ifdef _DEBUG
MsgDev( D_ERROR, "Stream_OpenMPG: failed to load (%s): %s\n", filename, get_error( mpeg ));
#else
MsgDev( D_ERROR, "Stream_OpenMPG: (%s) is probably corrupted\n", filename );
#endif
close_decoder( mpeg );
Mem_Free( stream );
FS_Close( file );
return NULL;
}
stream->buffsize = 0; // how many samples left from previous frame
stream->channels = mpegFile->channels;
stream->pos += mpegFile->outsize;
stream->rate = mpegFile->rate;
stream->channels = sc.channels;
stream->rate = sc.rate;
stream->width = 2; // always 16 bit
stream->ptr = mpegFile;
stream->ptr = mpeg;
stream->type = WF_MPGDATA;
return stream;
@ -208,43 +207,31 @@ long Stream_ReadMPG( stream_t *stream, long needBytes, void *buffer )
{
// buffer handling
int bytesWritten = 0;
int result;
mpeg_t *mpg;
void *mpg;
mpg = (mpeg_t *)stream->ptr;
Assert( mpg != NULL );
mpg = stream->ptr;
while( 1 )
{
long outsize;
byte *data;
long outsize;
if( !stream->buffsize )
{
result = read_mpeg_stream( mpg );
stream->pos += mpg->outsize;
if( result != MP3_OK )
{
// if there are no bytes remainig so we can decompress the new frame
result = read_mpeg_stream( mpg );
stream->pos += mpg->outsize;
if( result != MP3_OK )
break; // there was end of the stream
}
if( read_mpeg_stream( mpg, stream->temp, &stream->pos ) != MP3_OK )
break; // there was end of the stream
}
// check remaining size
if( bytesWritten + mpg->outsize > needBytes )
if( bytesWritten + stream->pos > needBytes )
outsize = ( needBytes - bytesWritten );
else outsize = mpg->outsize;
else outsize = stream->pos;
// copy raw sample to output buffer
data = (byte *)buffer + bytesWritten;
memcpy( data, &mpg->out[stream->buffsize], outsize );
memcpy( data, &stream->temp[stream->buffsize], outsize );
bytesWritten += outsize;
mpg->outsize -= outsize;
stream->pos -= outsize;
stream->buffsize += outsize;
// continue from this sample on a next call
@ -266,11 +253,9 @@ assume stream is valid
*/
long Stream_SetPosMPG( stream_t *stream, long newpos )
{
int newPos = set_stream_pos( stream->ptr, newpos );
if( newPos != -1 )
if( set_stream_pos( stream->ptr, newpos ) != -1 )
{
stream->pos = newPos;
// flush any previous data
stream->buffsize = 0;
return true;
}
@ -302,11 +287,14 @@ void Stream_FreeMPG( stream_t *stream )
{
if( stream->ptr )
{
mpeg_t *mpg;
close_decoder( stream->ptr );
stream->ptr = NULL;
}
mpg = (mpeg_t *)stream->ptr;
close_decoder( mpg );
Mem_Free( stream->ptr );
if( stream->file )
{
FS_Close( stream->file );
stream->file = NULL;
}
Mem_Free( stream );

View File

@ -405,7 +405,7 @@ assume stream is valid
*/
long Stream_ReadWAV( stream_t *stream, long bytes, void *buffer )
{
int samples, remaining;
int remaining;
if( !stream->file ) return 0; // invalid file
@ -414,7 +414,6 @@ long Stream_ReadWAV( stream_t *stream, long bytes, void *buffer )
if( bytes > remaining ) bytes = remaining;
stream->pos += bytes;
samples = ( bytes / stream->width ) / stream->channels;
FS_Read( stream->file, buffer, bytes );
return bytes;

View File

@ -19,6 +19,7 @@ GNU General Public License for more details.
#include "common.h"
#define FRAME_SIZE 32768 // must match with mp3 frame size
#define OUTBUF_SIZE 8192 // don't change!
typedef struct loadwavfmt_s
{
@ -63,17 +64,19 @@ typedef struct stream_s
{
const streamfmt_t *format; // streamformat to operate
// current stream state
// stream info
file_t *file; // stream file
int width; // resolution - num bits divided by 8 (8 bit is 1, 16 bit is 2)
int rate; // stream rate
int channels; // stream channels
int type; // wavtype
size_t size; // total stream size
int pos; // actual track position
// current stream state
void *ptr; // internal decoder state
char temp[OUTBUF_SIZE]; // mpeg decoder stuff
size_t pos; // actual track position (or actual buffer remains)
int buffsize; // cached buffer size
qboolean timejump; // true if position is changed
};
/*