diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index c6628db..b035e76 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(assets) add_subdirectory(duktape) +# add_subdirectory(flacplayer) add_executable(WiiDuktape main.c) target_link_libraries(WiiDuktape GRRLIB) diff --git a/source/flacplayer/CMakeLists.txt b/source/flacplayer/CMakeLists.txt new file mode 100644 index 0000000..986ca5c --- /dev/null +++ b/source/flacplayer/CMakeLists.txt @@ -0,0 +1,6 @@ +find_package(PkgConfig REQUIRED) +pkg_check_modules(FLAC REQUIRED flac) + +add_library(flacplayer flacplayer.c) +target_link_libraries(flacplayer PRIVATE ${FLAC_LIBRARIES}) +target_include_directories(flacplayer PRIVATE ${FLAC_INCLUDE_DIRS}) diff --git a/source/flacplayer/flacplayer.c b/source/flacplayer/flacplayer.c new file mode 100644 index 0000000..0440c93 --- /dev/null +++ b/source/flacplayer/flacplayer.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include + +static struct +{ + char *mem; + int size; + int pos; +} file[4]; + +#define READ_SAMPLES 4096 // samples that it must read before to send +#define MAX_PCMOUT 4096 // minimum size to read ogg samples +typedef struct +{ + // OggVorbis_File vf; + // vorbis_info *vi; + int current_section; + + // OGG file operation + int fd; + int mode; + int eof; + int flag; + int volume; + int seek_time; + + /* OGG buffer control */ + short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */ + int pcmout_pos; + int pcm_indx; + +} private_data_flac; + +static private_data_flac private_flac; + +// i don't know what this is doing at all +static int mem_open(char * ogg, int size) +{ + static int one = 1; + int n; + if (one) + { + one = 0; + for (n = 0; n < 4; n++) + file[n].size = 0; + } + + for (n = 0; n < 4; n++) + { + if (file[n].size == 0) + { + file[n].mem = ogg; + file[n].size = size; + file[n].pos = 0; + return (0x666 + n); + } + } + return -1; +} + + +FLAC__StreamDecoderReadStatus f_read(const FLAC__StreamDecoder * decoder, FLAC__byte buffer[], size_t * bites, void * client_data) { + int bytes = sizeof(FLAC__byte); + int blocks = *bites; + int * f = client_data; + void * punt = buffer; + + int b; + int c; + int d; + + if (bytes * blocks <= 0) + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + + blocks = bytes * blocks; + c = 0; + + while (blocks > 0) + { + b = blocks; + if (b > 4096) + b = 4096; + + if (*f >= 0x666 && *f <= 0x669) + { + d = (*f) - 0x666; + if (file[d].size == 0) + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + if ((file[d].pos + b) > file[d].size) + b = file[d].size - file[d].pos; + if (b > 0) + { + memcpy(punt, file[d].mem + file[d].pos, b); + file[d].pos += b; + } + } + else + b = read(*f, ((char *) punt) + c, b); + + if (b <= 0) + { + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + c += b; + blocks -= b; + } + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; +} + +FLAC__StreamDecoderSeekStatus f_seek(const FLAC__StreamDecoder * decoder, FLAC__uint64 absolute_byte_offset, void * client_data) { + int * f = client_data; + int mode = SEEK_SET; + unsigned long offset = absolute_byte_offset; + + if(f==NULL) return(FLAC__STREAM_DECODER_SEEK_STATUS_ERROR); + + int k, d; + mode &= 3; + if (*f >= 0x666 && *f <= 0x669) + { + d = (*f) - 0x666; + k = 0; + + if (file[d].size == 0) + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + + if (mode == 0) + { + if ((offset) >= file[d].size) + { + file[d].pos = file[d].size; + k = -1; + } + else if ((offset) < 0) + { + file[d].pos = 0; + k = -1; + } + else + file[d].pos = offset; + } + if (mode == 1) + { + if ((file[d].pos + offset) >= file[d].size) + { + file[d].pos = file[d].size; + k = -1; + } + else if ((file[d].pos + offset) < 0) + { + file[d].pos = 0; + k = -1; + } + else + file[d].pos += offset; + } + if (mode == 2) + { + + if ((file[d].size + offset) >= file[d].size) + { + file[d].pos = file[d].size; + k = -1; + } + else if ((file[d].size + offset) < 0) + { + file[d].pos = 0; + k = -1; + } + else + file[d].pos = file[d].size + offset; + } + + } + else + k = lseek(*f, (int) offset, mode); + + if (k < 0) + k = -1; + else + k = 0; + + if (k == -1) { + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + } else { + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; + } + + return k; +} + +int PlayFlac(const void * buffer, signed int len) { + + private_flac.fd = mem_open((char *)buffer, len); + + FLAC__StreamDecoder * decoder; + FLAC__StreamDecoderInitStatus init_status; + + decoder = FLAC__stream_decoder_new(); + + if (decoder == NULL) { + return 1; + } + + // init_status = FLAC__stream_decoder_init_stream(decoder); +}