Hi,
Not sure if this should be in the dev or users list, but here goes.
I am using the FLAC seekable stream decoder in my MACH3 laser games emulation
in MAME (www.boldtower.com/mach3). The game has a soundtrack (originally on
a laser disk) which I have flac encoded and play back in the game. I did the
implementation under Linux which works fine, the callbacks are easy to set up
and I've had no problems. I believe the code is OK because of this.
I am now trying to get it to work under Windows 2000 with Msys and gcc 3.2.
Everything compiles and links OK, but when it runs neither my flac_read, or
flac_write callback get called even though I call :
res = FLAC__seekable_stream_decoder_process_single(flacDecoder);
Has anyone else experienced this? What follows is the code I am using, my
program just sits looping in the while block in the flac_update function:
// callback for the stream
// we need to get length words from the flac decode into the buffer
static void flac_update(int param, INT16 *buffer, int length)
{
FLAC__bool res = true;
fprintf(stderr, "start flac_update...");
//TODO: check for playing? probably a better way to stop the sound
if(laserdisc_playing)
{
while(length && res)
{
// need to decode some more data
if(!decoded_samples)
{
// fprintf(stderr, "start flac_seekable_decoder_process...");
/*fprintf(stderr, "stat %d should be %d\n ",
FLAC__seekable_stream_decoder_get_state(flacDecoder),
FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC);
*/
res = FLAC__seekable_stream_decoder_process_single(flacDecoder);
// fprintf(stderr, "end flac_seekable_decoder_process\n");
}
while(decoded_samples && length)
{
*buffer++ = decoded_flac_channel[decode_buffer_pos++];
length--;
decoded_samples--;
}
}
}
else
{
/* clear the sound ? */
memset(buffer, 0, length << 1);
}
fprintf(stderr, "end flac_update\n");
}
static FLAC__SeekableStreamDecoderReadStatus flac_read(const
FLAC__SeekableStreamDecoder *decoder,
FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
fprintf(stderr, "flac_read start ...");
*bytes = mame_fread(flacFile, buffer, *bytes);
fprintf(stderr, "flac_read end %d\n ", *bytes);
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
}
static FLAC__SeekableStreamDecoderSeekStatus flac_seek(const
FLAC__SeekableStreamDecoder *decoder,
FLAC__uint64 absolute_byte_offset, void *client_data)
{
mame_fseek(flacFile, absolute_byte_offset, SEEK_SET);
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
static FLAC__SeekableStreamDecoderTellStatus flac_tell(const
FLAC__SeekableStreamDecoder *decoder,
FLAC__uint64 *absolute_byte_offset, void *client_data)
{
*absolute_byte_offset = mame_ftell(flacFile);
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
static FLAC__SeekableStreamDecoderLengthStatus flac_length(const
FLAC__SeekableStreamDecoder *decoder,
FLAC__uint64 *stream_length, void *client_data)
{
*stream_length = mame_fsize(flacFile);
return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
static FLAC__bool flac_eof(const FLAC__SeekableStreamDecoder *decoder, void
*client_data)
{
return(osd_feof(flacFile));
}
static FLAC__StreamDecoderWriteStatus flac_write(const
FLAC__SeekableStreamDecoder *decoder,
const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void
*client_data)
{
decode_flac_frame = frame;
decoded_flac_channel = buffer[0];
decoded_samples = frame->header.blocksize;
decode_buffer_pos = 0;
fprintf(stderr, "flac_write %d\n", decoded_samples);
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; // or ABORT
}
static void flac_metadata(const FLAC__SeekableStreamDecoder *decoder,
const FLAC__StreamMetadata *metadata, void *client_data)
{
}
static void flac_error(const FLAC__SeekableStreamDecoder *decoder,
FLAC__StreamDecoderErrorStatus status, void *client_data)
{
fprintf(stderr, "flac_error %d\n", status);
logerror("flac decode error %d\n", status);
}
static void init_flac(void)
{
fprintf(stderr, "init flac\n");
sprintf(flacFilename, "%s.flac", Machine->gamedrv->name);
flacFile = mame_fopen(Machine->gamedrv->name, flacFilename,
FILETYPE_LASERDISK_FLAC, 0);
if(flacFile)
{
flacDecoder = FLAC__seekable_stream_decoder_new();
fprintf(stderr, "got decoder\n");
if(!FLAC__seekable_stream_decoder_set_read_callback(flacDecoder,
flac_read)) fprintf(stderr, "Could not set flac read cb\n");
if(!FLAC__seekable_stream_decoder_set_seek_callback(flacDecoder,
flac_seek))
fprintf(stderr, "Could not set flac seek cb\n");
if(!FLAC__seekable_stream_decoder_set_tell_callback(flacDecoder,
flac_tell))
fprintf(stderr, "Could not set flac tell cb\n");
if(!FLAC__seekable_stream_decoder_set_length_callback(flacDecoder,
flac_length))
fprintf(stderr, "Could not set flac length cb\n");
fprintf(stderr, "set length decoder\n");
if(!FLAC__seekable_stream_decoder_set_eof_callback(flacDecoder, flac_eof))
fprintf(stderr, "Could not set flac eof cb\n");
if(!FLAC__seekable_stream_decoder_set_write_callback(flacDecoder,
flac_write))
fprintf(stderr, "Could not set flac write cb\n");
if(!FLAC__seekable_stream_decoder_set_metadata_callback(flacDecoder,
flac_metadata))
fprintf(stderr, "Could not set metadata cb\n");
if(!FLAC__seekable_stream_decoder_set_error_callback(flacDecoder,
flac_error))
fprintf(stderr, "Could not set flac error cb\n");
fprintf(stderr, "set error decoder\n");
if(FLAC__seekable_stream_decoder_init(flacDecoder)
!FLAC__SEEKABLE_STREAM_DECODER_OK)
{
fprintf(stderr, "flac init failed\n");
logerror("flac init failed\n");
}
}
else
{
fprintf(stderr, "flac file %s not found\n", flacFilename);
}
}