# HG changeset patch # User nenolod # Date 1159675131 25200 # Node ID 96901271d2e250f44dde015a74f8b6555fd735d9 # Parent 56c88eee9802c2e729310dc98c4900ec85627113 [svn] - fix crashing. works on my x64 box, static on bigendian (tested: x64-be, mips, ppc64) diff -r 56c88eee9802 -r 96901271d2e2 ChangeLog --- a/ChangeLog Sat Sep 30 19:26:34 2006 -0700 +++ b/ChangeLog Sat Sep 30 20:58:51 2006 -0700 @@ -1,3 +1,18 @@ +2006-10-01 02:26:34 +0000 William Pitcock + revision [112] + - experimental ALAC plugin -- don't use this, it crashes + + trunk/src/alac/Makefile | 14 + trunk/src/alac/alac.c | 1055 ++++++++++++++++++++++++++++++++++++++++++++++++ + trunk/src/alac/decomp.h | 13 + trunk/src/alac/demux.c | 693 +++++++++++++++++++++++++++++++ + trunk/src/alac/demux.h | 55 ++ + trunk/src/alac/plugin.c | 275 ++++++++++++ + trunk/src/alac/stream.c | 181 ++++++++ + trunk/src/alac/stream.h | 36 + + 8 files changed, 2322 insertions(+) + + 2006-10-01 01:32:24 +0000 William Pitcock revision [110] - alac support will be a seperate plugin diff -r 56c88eee9802 -r 96901271d2e2 src/alac/alac.c --- a/src/alac/alac.c Sat Sep 30 19:26:34 2006 -0700 +++ b/src/alac/alac.c Sat Sep 30 20:58:51 2006 -0700 @@ -48,6 +48,17 @@ (((v) & 0xFF00) >> 0x08); } while (0) +int host_bigendian; + +void set_endian() +{ + uint32_t integer = 0x000000aa; + unsigned char *p = (unsigned char*)&integer; + + if (p[0] == 0xaa) host_bigendian = 0; + else host_bigendian = 1; +} + struct alac_file { unsigned char *input_buffer; @@ -105,9 +116,8 @@ ptr += 4; /* 0 ? */ alac->setinfo_max_samples_per_frame = *(uint32_t*)ptr; /* buffer size / 2 ? */ -#ifndef WORDS_BIGENDIAN + if (!host_bigendian) _Swap32(alac->setinfo_max_samples_per_frame); -#endif ptr += 4; alac->setinfo_7a = *(uint8_t*)ptr; ptr += 1; @@ -122,24 +132,20 @@ alac->setinfo_7f = *(uint8_t*)ptr; ptr += 1; alac->setinfo_80 = *(uint16_t*)ptr; -#ifndef WORDS_BIGENDIAN + if (!host_bigendian) _Swap16(alac->setinfo_80); -#endif ptr += 2; alac->setinfo_82 = *(uint32_t*)ptr; -#ifndef WORDS_BIGENDIAN + if (!host_bigendian) _Swap32(alac->setinfo_82); -#endif ptr += 4; alac->setinfo_86 = *(uint32_t*)ptr; -#ifndef WORDS_BIGENDIAN + if (!host_bigendian) _Swap32(alac->setinfo_86); -#endif ptr += 4; alac->setinfo_8a_rate = *(uint32_t*)ptr; -#ifndef WORDS_BIGENDIAN + if (!host_bigendian) _Swap32(alac->setinfo_8a_rate); -#endif ptr += 4; allocate_buffers(alac); @@ -630,10 +636,11 @@ left = right + difference; /* output is always little endian */ -#ifdef WORDS_BIGENDIAN + if (host_bigendian) + { _Swap16(left); _Swap16(right); -#endif + } buffer_out[i*numchannels] = left; buffer_out[i*numchannels + 1] = right; @@ -651,10 +658,11 @@ right = buffer_b[i]; /* output is always little endian */ -#ifdef WORDS_BIGENDIAN + if (host_bigendian) + { _Swap16(left); _Swap16(right); -#endif + } buffer_out[i*numchannels] = left; buffer_out[i*numchannels + 1] = right; @@ -818,9 +826,8 @@ for (i = 0; i < outputsamples; i++) { int16_t sample = alac->outputsamples_buffer_a[i]; -#ifdef WORDS_BIGENDIAN + if (host_bigendian) _Swap16(sample); -#endif ((int16_t*)outbuffer)[i * alac->numchannels] = sample; } break; diff -r 56c88eee9802 -r 96901271d2e2 src/alac/plugin.c --- a/src/alac/plugin.c Sat Sep 30 19:26:34 2006 -0700 +++ b/src/alac/plugin.c Sat Sep 30 20:58:51 2006 -0700 @@ -47,11 +47,13 @@ static stream_t *input_stream; static int write_wav_format = 0; -static int verbose = 0; +static int verbose = 1; gpointer decode_thread(void *args); static GThread *playback_thread; +extern void set_endian(); + static void alac_init(void) { /* empty */ @@ -61,11 +63,10 @@ { demux_res_t demux_res; input_file = vfs_fopen(filename, "rb"); -#ifdef WORDS_BIGENDIAN input_stream = stream_create_file(input_file, 1); -#else - input_stream = stream_create_file(input_file, 0); -#endif + + set_endian(); + if (!input_stream) { fprintf(stderr, "failed to create input stream from file\n"); @@ -168,13 +169,14 @@ return 1; } -static void GetBuffer(demux_res_t *demux_res) +void GetBuffer(demux_res_t *demux_res) { unsigned long destBufferSize = 1024*16; /* 16kb buffer = 4096 frames = 1 alac sample */ void *pDestBuffer = malloc(destBufferSize); int bytes_read = 0; + int going = 1; - unsigned int buffer_size = 1024*64; + unsigned int buffer_size = 1024*128; void *buffer; unsigned int i; @@ -217,7 +219,7 @@ if (verbose) fprintf(stderr, "read %i bytes. total: %i\n", outputBytes, bytes_read); - produce_audio(get_written_time(), FMT_S16_LE, demux_res->num_channels, outputBytes, pDestBuffer, NULL); + produce_audio(alac_ip.output->written_time(), FMT_S16_LE, demux_res->num_channels, outputBytes, pDestBuffer, &going); } if (verbose) fprintf(stderr, "done reading, read %i frames\n", i); @@ -235,12 +237,13 @@ demux_res_t demux_res; unsigned int output_size, i; + set_endian(); + input_file = vfs_fopen((char *) args, "rb"); -#ifdef WORDS_BIGENDIAN input_stream = stream_create_file(input_file, 1); -#else - input_stream = stream_create_file(input_file, 0); -#endif + + printf("filename: %s\n", (char *) args); + if (!input_stream) { fprintf(stderr, "failed to create input stream from file\n"); @@ -258,6 +261,8 @@ /* initialise the sound converter */ init_sound_converter(&demux_res); + alac_ip.output->open_audio(FMT_S16_LE, demux_res.sample_rate, demux_res.num_channels); + /* will convert the entire buffer */ GetBuffer(&demux_res); @@ -266,6 +271,8 @@ if (input_opened) vfs_fclose(input_file); + alac_ip.output->close_audio(); + return NULL; } diff -r 56c88eee9802 -r 96901271d2e2 src/alac/stream.c --- a/src/alac/stream.c Sat Sep 30 19:26:34 2006 -0700 +++ b/src/alac/stream.c Sat Sep 30 20:58:51 2006 -0700 @@ -50,18 +50,14 @@ v = (((v) & 0x00FF) << 0x08) | \ (((v) & 0xFF00) >> 0x08); } while (0) -#ifdef WORDS_BIGENDIAN -int host_bigendian = 1; -#else -int host_bigendian = 0; -#endif - struct stream_tTAG { VFSFile *f; int bigendian; int eof; }; +extern int host_bigendian; + void stream_read(stream_t *stream, size_t size, void *buf) { size_t ret;