2015-01-25 06:08:25 +01:00
|
|
|
#include "coding.h"
|
2017-04-29 22:37:15 +02:00
|
|
|
|
|
|
|
#ifdef VGM_USE_G719
|
2018-09-04 17:08:01 +02:00
|
|
|
#define G719_MAX_CODES ((1280/8)) /* in int16, so max frame size is (value/8)*2 (known values: 0xF0=common, 0x140=rare) */
|
2018-08-14 22:20:36 +02:00
|
|
|
|
2015-01-25 06:08:25 +01:00
|
|
|
|
2017-10-14 12:41:59 +02:00
|
|
|
g719_codec_data *init_g719(int channel_count, int frame_size) {
|
|
|
|
int i;
|
|
|
|
g719_codec_data *data = NULL;
|
|
|
|
|
2018-08-14 22:20:36 +02:00
|
|
|
if (frame_size / sizeof(int16_t) > G719_MAX_CODES)
|
|
|
|
goto fail;
|
|
|
|
|
2017-10-14 12:41:59 +02:00
|
|
|
data = calloc(channel_count, sizeof(g719_codec_data)); /* one decoder per channel */
|
|
|
|
if (!data) goto fail;
|
|
|
|
|
|
|
|
for (i = 0; i < channel_count; i++) {
|
|
|
|
data[i].handle = g719_init(frame_size); /* Siren 22 == 22khz bandwidth */
|
|
|
|
if (!data[i].handle) goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
if (data) {
|
|
|
|
for (i = 0; i < channel_count; i++) {
|
|
|
|
g719_free(data[i].handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(data);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-08-14 22:20:36 +02:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
void decode_g719(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel) {
|
2015-01-25 06:08:25 +01:00
|
|
|
VGMSTREAMCHANNEL *ch = &vgmstream->ch[channel];
|
|
|
|
g719_codec_data *data = vgmstream->codec_data;
|
|
|
|
g719_codec_data *ch_data = &data[channel];
|
|
|
|
int i;
|
|
|
|
|
2018-08-14 22:20:36 +02:00
|
|
|
if (0 == vgmstream->samples_into_block) {
|
|
|
|
int16_t code_buffer[G719_MAX_CODES];
|
2015-01-25 06:08:25 +01:00
|
|
|
vgmstream->ch[channel].streamfile->read(ch->streamfile, (uint8_t*)code_buffer, ch->offset, vgmstream->interleave_block_size);
|
|
|
|
g719_decode_frame(ch_data->handle, code_buffer, ch_data->buffer);
|
|
|
|
}
|
|
|
|
|
2018-08-14 22:20:36 +02:00
|
|
|
for (i = 0; i < samples_to_do; i++) {
|
2015-01-25 06:08:25 +01:00
|
|
|
outbuf[i*channelspacing] = ch_data->buffer[vgmstream->samples_into_block+i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
|
|
|
|
void reset_g719(VGMSTREAM *vgmstream) {
|
|
|
|
g719_codec_data *data = vgmstream->codec_data;
|
|
|
|
int i;
|
2018-03-10 16:59:00 +01:00
|
|
|
if (!data) return;
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2018-08-14 22:20:36 +02:00
|
|
|
for (i = 0; i < vgmstream->channels; i++) {
|
2017-04-29 22:37:15 +02:00
|
|
|
g719_reset(data[i].handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_g719(VGMSTREAM *vgmstream) {
|
|
|
|
g719_codec_data *data = (g719_codec_data *) vgmstream->codec_data;
|
2018-08-14 22:20:36 +02:00
|
|
|
int i;
|
|
|
|
if (!data) return;
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2018-08-14 22:20:36 +02:00
|
|
|
for (i = 0; i < vgmstream->channels; i++) {
|
|
|
|
g719_free(data[i].handle);
|
2017-04-29 22:37:15 +02:00
|
|
|
}
|
2018-08-14 22:20:36 +02:00
|
|
|
free(data);
|
2017-04-29 22:37:15 +02:00
|
|
|
}
|
|
|
|
|
2015-01-25 06:08:25 +01:00
|
|
|
#endif
|