ref: c8ea3edb24db14c9a4386d458b0823c297cae5fc
parent: 5db3932b157d501a27dbbf82975384a605a5907a
author: Gregory Maxwell <[email protected]>
date: Fri Aug 19 08:18:16 EDT 2011
Switch the encode and decode tools to use the float API and update for the VBR API change.
--- a/src/opusdec.c
+++ b/src/opusdec.c
@@ -339,39 +339,47 @@
return st;
}
-void audio_write(opus_int16 *pcm, int channels, int frame_size, FILE *fout, SpeexResamplerState *resampler, int *skip)
+void audio_write(float *pcm, int channels, int frame_size, FILE *fout, SpeexResamplerState *resampler, int *skip, int file)
{
- if (resampler)
- {
- opus_int16 buf[2048];
- do {
- int tmp_skip;
- unsigned in_len, out_len;
- in_len = frame_size;
- out_len = 1024;
- speex_resampler_process_interleaved_int(resampler, pcm, &in_len, buf, &out_len);
- if (skip)
- {
- tmp_skip = (*skip>out_len) ? out_len : *skip;
- *skip -= tmp_skip;
- } else {
- tmp_skip = 0;
- }
- fwrite(buf+tmp_skip*channels, 2, (out_len-tmp_skip)*channels, fout);
- pcm += channels*in_len;
- frame_size -= in_len;
- } while (frame_size != 0);
- } else {
- int tmp_skip;
- if (skip)
- {
- tmp_skip = (*skip>frame_size) ? frame_size : *skip;
- *skip -= tmp_skip;
- } else {
- tmp_skip = 0;
- }
- fwrite(pcm+tmp_skip*channels, 2, (frame_size-tmp_skip)*channels, fout);
- }
+ int i,tmp_skip;
+ unsigned out_len;
+ short out[2048];
+ float buf[2048];
+ float *output;
+
+ do {
+ if (resampler){
+ output=buf;
+ unsigned in_len;
+ in_len = frame_size;
+ out_len = 1024;
+ speex_resampler_process_interleaved_float(resampler, pcm, &in_len, buf, &out_len);
+ pcm += channels*in_len;
+ frame_size -= in_len;
+ } else {
+ output=pcm;
+ out_len=frame_size;
+ frame_size=0;
+ }
+
+ if (skip){
+ tmp_skip = (*skip>out_len) ? out_len : *skip;
+ *skip -= tmp_skip;
+ } else {
+ tmp_skip = 0;
+ }
+
+ /*Convert to short and save to output file*/
+ /*FIXME: This should dither for integer output*/
+ if (file){
+ for (i=0;i<out_len*channels;i++)
+ out[i]=le_short((short)lrintf(fmax(fmin(output[i]*32768.f+0.5f,32767),-32768)));
+ } else {
+ for (i=0;i<out_len*channels;i++)
+ out[i]=(short)lrintf(fmax(fmin(output[i]*32768.f+0.5f,32767),-32768));
+ }
+ fwrite(out+tmp_skip*channels, 2, (out_len-tmp_skip)*channels, fout);
+ } while (frame_size != 0);
}
int main(int argc, char **argv)
@@ -380,8 +388,7 @@
int option_index = 0;
char *inFile, *outFile;
FILE *fin, *fout=NULL;
- opus_int16 out[MAX_FRAME_SIZE];
- opus_int16 output[MAX_FRAME_SIZE];
+ float output[MAX_FRAME_SIZE];
int frame_size=0;
void *st=NULL;
int packet_count=0;
@@ -585,9 +592,9 @@
int ret;
/*Decode frame*/
if (!lost)
- ret = opus_decode(st, (unsigned char*)op.packet, op.bytes, output, MAX_FRAME_SIZE, 0);
+ ret = opus_decode_float(st, (unsigned char*)op.packet, op.bytes, output, MAX_FRAME_SIZE, 0);
else
- ret = opus_decode(st, NULL, 0, output, MAX_FRAME_SIZE, 0);
+ ret = opus_decode_float(st, NULL, 0, output, MAX_FRAME_SIZE, 0);
/*for (i=0;i<frame_size*channels;i++)
printf ("%d\n", (int)output[i]);*/
@@ -598,13 +605,11 @@
break;
}
frame_size = ret;
+
/* Apply header gain */
for (i=0;i<frame_size*channels;i++)
- {
- float tmp = gain*output[i];
- tmp = (tmp < -32767) ? -32767 : ((tmp > 32767) ? 32767 : tmp);
- output[i] = floor(.5+tmp);
- }
+ output[i] *= gain;
+
if (print_bitrate) {
opus_int32 tmp=op.bytes;
char ch=13;
@@ -616,21 +621,12 @@
truncate = decoded-page_granule;
else
truncate = 0;
- /*Convert to short and save to output file*/
- if (strlen(outFile)!=0)
{
- for (i=0;i<frame_size*channels;i++)
- out[i]=le_short(output[i]);
- } else {
- for (i=0;i<frame_size*channels;i++)
- out[i]=output[i];
- }
- {
int new_frame_size;
if (truncate > frame_size)
truncate = frame_size;
new_frame_size = frame_size - truncate;
- audio_write(out, channels, new_frame_size, fout, resampler, &preskip);
+ audio_write(output, channels, new_frame_size, fout, resampler, &preskip, strlen(outFile)==0);
audio_size+=sizeof(short)*new_frame_size*channels;
}
}
@@ -647,7 +643,7 @@
if (resampler)
{
int i;
- opus_int16 zeros[200];
+ float zeros[200];
int drain;
for (i=0;i<200;i++)
@@ -657,7 +653,7 @@
int tmp = drain;
if (tmp > 100)
tmp = 100;
- audio_write(zeros, channels, tmp, fout, resampler, NULL);
+ audio_write(zeros, channels, tmp, fout, resampler, NULL, strlen(outFile)==0);
drain -= tmp;
} while (drain>0);
}
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -77,7 +77,7 @@
/* Convert input audio bits, endians and channels */
static int read_samples_pcm(FILE *fin,int frame_size, int bits, int channels,
- int lsb, short * input, char *buff, opus_int32 *size,
+ int lsb, float * input, char *buff, opus_int32 *size,
int *extra_samples)
{
short s[MAX_FRAME_SIZE];
@@ -133,11 +133,10 @@
}
}
- /* FIXME: This is probably redundent now */
/* copy to float input buffer */
for (i=0;i<frame_size*channels;i++)
{
- input[i]=s[i];
+ input[i]=s[i]*(1/32768.f);
}
for (i=nb_read*channels;i<frame_size*channels;i++)
@@ -158,13 +157,13 @@
}
static int read_samples(FILE *fin,int frame_size, int bits, int channels,
- int lsb, short * input, char *buff, opus_int32 *size,
+ int lsb, float * input, char *buff, opus_int32 *size,
SpeexResamplerState *resampler, int *extra_samples)
{
if (resampler)
{
/* FIXME: This is a hack, get rid of these static variables */
- static opus_int16 pcmbuf[2048];
+ static float pcmbuf[2048];
static int inbuf=0;
int out_samples=0;
while (out_samples<frame_size)
@@ -177,7 +176,7 @@
inbuf += ret;
in_len = inbuf;
out_len = frame_size-out_samples;
- speex_resampler_process_interleaved_int(resampler, pcmbuf, &in_len, input+out_samples*channels, &out_len);
+ speex_resampler_process_interleaved_float(resampler, pcmbuf, &in_len, input+out_samples*channels, &out_len);
if (ret==0 && in_len==0)
{
for (i=out_samples*channels;i<frame_size*channels;i++)
@@ -257,7 +256,7 @@
int option_index = 0;
char *inFile, *outFile;
FILE *fin, *fout;
- short input[MAX_FRAME_SIZE];
+ float input[MAX_FRAME_SIZE];
opus_int32 frame_size = 960;
int quiet=0;
int nbBytes;
@@ -540,7 +539,7 @@
}
if (!with_cbr)
{
- if (opus_encoder_ctl(st, OPUS_SET_VBR_FLAG(1)) != OPUS_OK)
+ if (opus_encoder_ctl(st, OPUS_SET_VBR(1)) != OPUS_OK)
{
fprintf (stderr, "VBR request failed\n");
return 1;
@@ -647,7 +646,7 @@
id++;
/*Encode current frame*/
- nbBytes = opus_encode(st, input, frame_size, bits, bytes_per_packet);
+ nbBytes = opus_encode_float(st, input, frame_size, bits, bytes_per_packet);
if (nbBytes<0)
{
fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes);