diff --git a/src/coding/acm_decoder.c b/src/coding/acm_decoder.c index edc53d74..e1dd102c 100644 --- a/src/coding/acm_decoder.c +++ b/src/coding/acm_decoder.c @@ -817,23 +817,76 @@ void acm_reset(ACMStream *acm) memset(acm->wrapbuf, 0, acm->wrapbuf_len * sizeof(int)); } -/* interface to vgmstream */ -void decode_acm(ACMStream * acm, sample * outbuf, - int32_t samples_to_do, int channelspacing) { + +/*********************************************** + * interface to vgmstream + ***********************************************/ + +mus_acm_codec_data *init_acm(int files) { + mus_acm_codec_data* data = NULL; + + if (files == 0) + goto fail; + + data = calloc(1,sizeof(mus_acm_codec_data)); + if (!data) goto fail; + + data->files = calloc(files,sizeof(ACMStream *)); + if (!data->files) goto fail; + + data->file_count = files; + data->current_file = 0; + + return data; + +fail: + free_acm(data); + return NULL; +} + +void decode_acm(ACMStream * acm, sample * outbuf, int32_t samples_to_do, int channelspacing) { int32_t samples_read = 0; while (samples_read < samples_to_do) { - int32_t bytes_read_just_now; - bytes_read_just_now = - acm_read(acm,(char*)( - outbuf+samples_read*channelspacing), - (samples_to_do-samples_read)*sizeof(sample)* - channelspacing,0,2,1); + int32_t bytes_read_just_now = acm_read( + acm, + (char*)(outbuf+samples_read*channelspacing), + (samples_to_do-samples_read)*sizeof(sample)*channelspacing, + 0,2,1); if (bytes_read_just_now > 0) { - samples_read += - bytes_read_just_now/sizeof(sample)/channelspacing; + samples_read += bytes_read_just_now/sizeof(sample)/channelspacing; } else { return; } } } + +void reset_acm(VGMSTREAM *vgmstream) { + mus_acm_codec_data *data = vgmstream->codec_data; + int i; + if (data) { + data->current_file = 0; + for (i=0;ifile_count;i++) { + acm_reset(data->files[i]); + } + } +} + +void free_acm(mus_acm_codec_data *data) { + if (data) { + if (data->files) { + int i; + for (i = 0; i < data->file_count; i++) { + /* shouldn't be duplicates */ + if (data->files[i]) { + acm_close(data->files[i]); + } + + } + free(data->files); + } + + free(data); + } +} + diff --git a/src/coding/coding.h b/src/coding/coding.h index b54c7631..4488dace 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -102,7 +102,10 @@ void decode_cbd2_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspac void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); /* acm_decoder */ +mus_acm_codec_data *init_acm(int files); void decode_acm(ACMStream * acm, sample * outbuf, int32_t samples_to_do, int channelspacing); +void reset_acm(VGMSTREAM *vgmstream); +void free_acm(mus_acm_codec_data *data); /* nwa_decoder */ void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do); diff --git a/src/meta/acm.c b/src/meta/acm.c index 45ed0541..1a3bd426 100644 --- a/src/meta/acm.c +++ b/src/meta/acm.c @@ -1,10 +1,8 @@ -#include "../vgmstream.h" #include "meta.h" -#include "../util.h" +#include "../coding/coding.h" #include "../coding/acm_decoder.h" -/* InterPlay ACM */ -/* The real work is done by libacm */ +/* ACM - InterPlay infinity engine games [Planescape: Torment (PC), Baldur's Gate (PC)] */ VGMSTREAM * init_vgmstream_acm(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; int loop_flag = 0, channel_count, sample_rate, num_samples; @@ -19,15 +17,8 @@ VGMSTREAM * init_vgmstream_acm(STREAMFILE *streamFile) { /* init decoder */ - { - data = calloc(1,sizeof(mus_acm_codec_data)); - if (!data) goto fail; - - data->current_file = 0; - data->file_count = 1; - data->files = calloc(data->file_count,sizeof(ACMStream *)); - if (!data->files) goto fail; - } + data = init_acm(1); + if (!data) goto fail; /* open and parse the file before creating the vgmstream */ { @@ -62,16 +53,7 @@ VGMSTREAM * init_vgmstream_acm(STREAMFILE *streamFile) { return vgmstream; fail: - if (data && (!vgmstream || !vgmstream->codec_data)) { - if (data) { - int i; - for (i = 0; i < data->file_count; i++) { - acm_close(data->files[i]); - } - free(data->files); - free(data); - } - } + free_acm(data); close_vgmstream(vgmstream); return NULL; } diff --git a/src/vgmstream.c b/src/vgmstream.c index 1aca8564..13ce0774 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -571,14 +571,7 @@ void reset_vgmstream(VGMSTREAM * vgmstream) { #endif if (vgmstream->coding_type==coding_ACM) { - mus_acm_codec_data *data = vgmstream->codec_data; - int i; - if (data) { - data->current_file = 0; - for (i=0;ifile_count;i++) { - acm_reset(data->files[i]); - } - } + reset_acm(vgmstream); } if ( @@ -764,25 +757,8 @@ void close_vgmstream(VGMSTREAM * vgmstream) { #endif if (vgmstream->coding_type==coding_ACM) { - mus_acm_codec_data *data = (mus_acm_codec_data *) vgmstream->codec_data; - - if (data) { - if (data->files) { - int i; - for (i=0; ifile_count; i++) { - /* shouldn't be duplicates */ - if (data->files[i]) { - acm_close(data->files[i]); - data->files[i] = NULL; - } - } - free(data->files); - data->files = NULL; - } - - free(vgmstream->codec_data); - vgmstream->codec_data = NULL; - } + free_acm(vgmstream->codec_data); + vgmstream->codec_data = NULL; } if ( @@ -1818,10 +1794,10 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to vgmstream->channels); break; #endif - case coding_ACM: { + case coding_ACM: { //single ACM mus_acm_codec_data *data = vgmstream->codec_data; ACMStream *acm; - + acm = data->files[data->current_file]; decode_acm(acm, buffer+samples_written*vgmstream->channels,