almost works. samples are mangled

This commit is contained in:
Bill Currie 2005-06-15 11:56:03 +00:00
parent 98f53c2c1c
commit 13e8b00da5

View file

@ -45,6 +45,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include <stdlib.h> #include <stdlib.h>
#include <FLAC/seekable_stream_decoder.h> #include <FLAC/seekable_stream_decoder.h>
#include <FLAC/metadata.h>
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/quakefs.h" #include "QF/quakefs.h"
@ -63,6 +64,12 @@ typedef struct {
int pos; int pos;
} flacfile_t; } flacfile_t;
static void
error_func (const FLAC__SeekableStreamDecoder *decoder,
FLAC__StreamDecoderErrorStatus status, void *client_data)
{
}
static FLAC__SeekableStreamDecoderReadStatus static FLAC__SeekableStreamDecoderReadStatus
read_func (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], read_func (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[],
unsigned *bytes, void *client_data) unsigned *bytes, void *client_data)
@ -113,6 +120,9 @@ write_func (const FLAC__SeekableStreamDecoder *decoder,
{ {
flacfile_t *ff = (flacfile_t *) client_data; flacfile_t *ff = (flacfile_t *) client_data;
int bps = ff->info.bits_per_sample / 8; int bps = ff->info.bits_per_sample / 8;
if (!ff->buffer)
ff->buffer = malloc (ff->info.max_blocksize * ff->info.channels * bps);
if (ff->info.channels == 1) { if (ff->info.channels == 1) {
memcpy (ff->buffer, buffer[0], bps * frame->header.blocksize); memcpy (ff->buffer, buffer[0], bps * frame->header.blocksize);
} else { } else {
@ -150,6 +160,8 @@ meta_func (const FLAC__SeekableStreamDecoder *decoder,
flacfile_t *ff = (flacfile_t *) client_data; flacfile_t *ff = (flacfile_t *) client_data;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
ff->info = metadata->data.stream_info; ff->info = metadata->data.stream_info;
if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
ff->vorbis_info = FLAC__metadata_object_clone (metadata);
} }
static flacfile_t * static flacfile_t *
@ -159,6 +171,7 @@ open_flac (QFile *file)
ff->decoder = FLAC__seekable_stream_decoder_new (); ff->decoder = FLAC__seekable_stream_decoder_new ();
ff->file = file; ff->file = file;
FLAC__seekable_stream_decoder_set_error_callback (ff->decoder, error_func);
FLAC__seekable_stream_decoder_set_read_callback (ff->decoder, read_func); FLAC__seekable_stream_decoder_set_read_callback (ff->decoder, read_func);
FLAC__seekable_stream_decoder_set_seek_callback (ff->decoder, seek_func); FLAC__seekable_stream_decoder_set_seek_callback (ff->decoder, seek_func);
FLAC__seekable_stream_decoder_set_tell_callback (ff->decoder, tell_func); FLAC__seekable_stream_decoder_set_tell_callback (ff->decoder, tell_func);
@ -169,8 +182,10 @@ open_flac (QFile *file)
FLAC__seekable_stream_decoder_set_metadata_callback (ff->decoder, FLAC__seekable_stream_decoder_set_metadata_callback (ff->decoder,
meta_func); meta_func);
FLAC__seekable_stream_decoder_set_client_data (ff->decoder, ff); FLAC__seekable_stream_decoder_set_client_data (ff->decoder, ff);
FLAC__seekable_stream_decoder_set_metadata_respond (ff->decoder,
FLAC__METADATA_TYPE_VORBIS_COMMENT);
FLAC__seekable_stream_decoder_init (ff->decoder); Sys_DPrintf ("%s\n", FLAC__SeekableStreamDecoderStateString[FLAC__seekable_stream_decoder_init (ff->decoder)]);
FLAC__seekable_stream_decoder_process_until_end_of_metadata (ff->decoder); FLAC__seekable_stream_decoder_process_until_end_of_metadata (ff->decoder);
return ff; return ff;
} }
@ -181,6 +196,12 @@ close_flac (flacfile_t *ff)
FLAC__seekable_stream_decoder_finish (ff->decoder); FLAC__seekable_stream_decoder_finish (ff->decoder);
FLAC__seekable_stream_decoder_delete (ff->decoder); FLAC__seekable_stream_decoder_delete (ff->decoder);
if (ff->vorbis_info)
FLAC__metadata_object_delete (ff->vorbis_info);
if (ff->buffer)
free (ff->buffer);
Qclose (ff->file); Qclose (ff->file);
free (ff); free (ff);
@ -190,18 +211,21 @@ static int
flac_read (flacfile_t *ff, byte *buf, int len) flac_read (flacfile_t *ff, byte *buf, int len)
{ {
int count = 0; int count = 0;
int bps = ff->info.channels * ff->info.bits_per_sample / 8;
while (len) { while (len) {
int res = 0; int res = 0;
if (ff->size == ff->pos) if (ff->size == ff->pos)
FLAC__seekable_stream_decoder_process_single (ff->decoder); FLAC__seekable_stream_decoder_process_single (ff->decoder);
res = ff->size - ff->pos; res = (ff->size - ff->pos) * bps;
if (res > len) if (res > len)
res = len; res = len;
if (res > 0) { if (res > 0) {
memcpy (buf, ff->buffer + ff->pos, res);
count += res; count += res;
len -= res; len -= res;
buf += res; buf += res;
ff->pos += res / bps;
} else if (res < 0) { } else if (res < 0) {
Sys_Printf ("flac error %d\n", res); Sys_Printf ("flac error %d\n", res);
return -1; return -1;
@ -300,7 +324,8 @@ flac_stream_read (void *file, byte *buf, int count, wavinfo_t *info)
static int static int
flac_stream_seek (void *file, int pos, wavinfo_t *info) flac_stream_seek (void *file, int pos, wavinfo_t *info)
{ {
return FLAC__seekable_stream_decoder_seek_absolute (file, pos); flacfile_t *ff = file;
return FLAC__seekable_stream_decoder_seek_absolute (ff->decoder, pos);
} }
static void static void
@ -377,13 +402,14 @@ flac_stream (sfx_t *sfx, char *realname, flacfile_t *ff, wavinfo_t info)
{ {
sfxstream_t *stream = calloc (1, sizeof (sfxstream_t)); sfxstream_t *stream = calloc (1, sizeof (sfxstream_t));
close_flac (ff);
sfx->open = flac_stream_open; sfx->open = flac_stream_open;
sfx->wavinfo = SND_CacheWavinfo; sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain; sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease; sfx->release = SND_StreamRelease;
sfx->data = stream; sfx->data = stream;
stream->file = ff; stream->file = realname;
stream->wavinfo = info; stream->wavinfo = info;
} }
@ -393,15 +419,15 @@ get_info (flacfile_t *ff)
int sample_start = -1, sample_count = 0; int sample_start = -1, sample_count = 0;
int samples; int samples;
wavinfo_t info; wavinfo_t info;
FLAC__StreamMetadata_VorbisComment *vc; FLAC__StreamMetadata_VorbisComment *vc = 0;
FLAC__StreamMetadata_VorbisComment_Entry *ve; FLAC__StreamMetadata_VorbisComment_Entry *ve;
FLAC__uint32 i; FLAC__uint32 i;
samples = ff->info.total_samples; samples = ff->info.total_samples;
if (ff->vorbis_info) {
vc = &ff->vorbis_info->data.vorbis_comment; vc = &ff->vorbis_info->data.vorbis_comment;
for (i = 0, ve = vc->comments; for (i = 0, ve = vc->comments; i < vc->num_comments; ve++, i++) {
i < ff->vorbis_info->data.vorbis_comment.num_comments; ve++) {
Sys_DPrintf ("%.*s\n", ve->length, ve->entry); Sys_DPrintf ("%.*s\n", ve->length, ve->entry);
if (strncmp ("CUEPOINT=", ve->entry, 9) == 0) { if (strncmp ("CUEPOINT=", ve->entry, 9) == 0) {
char *str = alloca (ve->length + 1); char *str = alloca (ve->length + 1);
@ -410,6 +436,7 @@ get_info (flacfile_t *ff)
sscanf (str + 9, "%d %d", &sample_start, &sample_count); sscanf (str + 9, "%d %d", &sample_start, &sample_count);
} }
} }
}
if (sample_start != -1) if (sample_start != -1)
samples = sample_start + sample_count; samples = sample_start + sample_count;
@ -427,9 +454,11 @@ get_info (flacfile_t *ff)
info.channels, info.rate); info.channels, info.rate);
Sys_Printf ("\nDecoded length: %d samples (%d bytes)\n", Sys_Printf ("\nDecoded length: %d samples (%d bytes)\n",
info.samples, info.samples * info.channels * 2); info.samples, info.samples * info.channels * 2);
if (vc) {
Sys_Printf ("Encoded by: %.*s\n\n", Sys_Printf ("Encoded by: %.*s\n\n",
vc->vendor_string.length, vc->vendor_string.entry); vc->vendor_string.length, vc->vendor_string.entry);
} }
}
return info; return info;
} }