#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "celt.h"
int
main(int argc, char **argv) {
char data[2048] = { };
short pcm[2048] = { };
int rate = 48000;
int framesize = 960;
int channels = 1;
int tmp;
int rem;
void *mode;
void *state;
uint16_t len;
while ((tmp = getopt(argc, argv, "r:f:c:")) != -1) {
switch (tmp) {
case 'r':
rate = atoi(optarg);
break;
case 'f':
framesize = atoi(optarg);
break;
case 'c':
channels = atoi(optarg);
break;
}
}
if (!(mode = celt_mode_create(rate, framesize, &tmp))) {
fprintf(stderr, "error: celt_mode_create: %s\n", celt_strerror(tmp));
return 1;
}
if (!(state = celt_decoder_create_custom(mode, channels, &tmp))) {
fprintf(stderr, "error: celt_decoder_create_custom: %s\n", celt_strerror(tmp));
celt_mode_destroy(mode);
return 1;
}
for (len = 0;;) {
if (!len) {
if (read(STDIN_FILENO, &len, sizeof(len)) != sizeof(len)) {
break;
}
if (len > sizeof(data)) {
fprintf(stderr, "error: celt packet larger than buffer\n");
celt_decoder_destroy(state);
celt_mode_destroy(mode);
return 1;
}
rem = len;
}
if ((tmp = read(STDIN_FILENO, data + (len - rem), rem)) < 0) {
fprintf(stderr, "error: read: %s\n", strerror(errno));
celt_decoder_destroy(state);
celt_mode_destroy(mode);
return 1;
}
if (!tmp) {
break;
}
if (tmp != rem) {
rem -= tmp;
continue;
}
if ((tmp = celt_decode(state, (void *)data, len, pcm, framesize)) < 0) {
fprintf(stderr, "error: celt_decode: %s\n", celt_strerror(tmp));
celt_decoder_destroy(state);
celt_mode_destroy(mode);
return 1;
}
len = 0;
if (write(STDOUT_FILENO, pcm, sizeof(*pcm) * framesize * channels) < 0) {
fprintf(stderr, "error: write: %s\n", strerror(errno));
celt_decoder_destroy(state);
celt_mode_destroy(mode);
return 1;
}
}
celt_decoder_destroy(state);
celt_mode_destroy(mode);
return 0;
}