|
|
|
@ -98,6 +98,7 @@ typedef struct { |
|
|
|
|
int blocksize[2]; // in (1<<n) format
|
|
|
|
|
MDCTContext mdct[2]; |
|
|
|
|
const float * win[2]; |
|
|
|
|
int have_saved; |
|
|
|
|
float * saved; |
|
|
|
|
float * samples; |
|
|
|
|
float * floor; // also used for tmp values for mdct
|
|
|
|
@ -339,6 +340,7 @@ static void create_vorbis_context(venc_context_t * venc, AVCodecContext * avccon |
|
|
|
|
venc->modes[0].blockflag = 0; |
|
|
|
|
venc->modes[0].mapping = 0; |
|
|
|
|
|
|
|
|
|
venc->have_saved = 0; |
|
|
|
|
venc->saved = av_malloc(sizeof(float) * venc->channels * (1 << venc->blocksize[1]) / 2); |
|
|
|
|
venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->blocksize[1])); |
|
|
|
|
venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->blocksize[1]) / 2); |
|
|
|
@ -611,6 +613,53 @@ static int vorbis_encode_init(AVCodecContext * avccontext) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int window(venc_context_t * venc, signed short * audio, int samples) { |
|
|
|
|
int i, j, channel; |
|
|
|
|
const float * win = venc->win[0]; |
|
|
|
|
int window_len = 1 << (venc->blocksize[0] - 1); |
|
|
|
|
// FIXME use dsp
|
|
|
|
|
|
|
|
|
|
if (!venc->have_saved && !samples) return 0; |
|
|
|
|
|
|
|
|
|
if (venc->have_saved) { |
|
|
|
|
for (channel = 0; channel < venc->channels; channel++) { |
|
|
|
|
memcpy(venc->samples + channel*window_len*2, venc->saved + channel*window_len, sizeof(float)*window_len); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
for (channel = 0; channel < venc->channels; channel++) { |
|
|
|
|
memset(venc->samples + channel*window_len*2, 0, sizeof(float)*window_len); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (samples) { |
|
|
|
|
for (channel = 0; channel < venc->channels; channel++) { |
|
|
|
|
float * offset = venc->saved + channel*window_len*2 + window_len; |
|
|
|
|
j = channel; |
|
|
|
|
for (i = 0; i < samples; i++, j += venc->channels) |
|
|
|
|
offset[i] = audio[j] / 32768. * win[window_len - i]; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
for (channel = 0; channel < venc->channels; channel++) { |
|
|
|
|
memset(venc->samples + channel*window_len*2 + window_len, 0, sizeof(float)*window_len); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (channel = 0; channel < venc->channels; channel++) { |
|
|
|
|
ff_mdct_calc(&venc->mdct[0], venc->coeffs + channel*window_len, venc->samples + channel*window_len*2, venc->floor/*tmp*/); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (samples) { |
|
|
|
|
for (channel = 0; channel < venc->channels; channel++) { |
|
|
|
|
j = channel; |
|
|
|
|
for (i = 0; i < samples; i++, j += venc->channels) |
|
|
|
|
venc->saved[i] = audio[j] / 32768. * win[i]; |
|
|
|
|
} |
|
|
|
|
venc->have_saved = 1; |
|
|
|
|
} else { |
|
|
|
|
venc->have_saved = 0; |
|
|
|
|
} |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int vorbis_encode_frame(AVCodecContext * avccontext, unsigned char * packets, int buf_size, void *data) |
|
|
|
|
{ |
|
|
|
@ -622,6 +671,8 @@ static int vorbis_encode_frame(AVCodecContext * avccontext, unsigned char * pack |
|
|
|
|
PutBitContext pb; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
if (!window(venc, audio, samples)) return 0; |
|
|
|
|
|
|
|
|
|
init_put_bits(&pb, packets, buf_size); |
|
|
|
|
|
|
|
|
|
put_bits(&pb, 1, 0); // magic bit
|
|
|
|
|