#include <stdio.h>
#include "all.h"
#include <libavdevice/avdevice.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <speex/speex.h>
static AVFormatContext *fctx = NULL;
static AVCodecContext *dctx = NULL;
static void *estate;
static SpeexBits ebits;
static int speex_frame_samples;
SpeexEchoState *echo_state;
void error2(const char *str, int i) {
fprintf(stderr, "%s: %i\n", str, i);
abort();
}
void new_for_speex(const short *data, int samples) {
static short storage[1000];
static int nread = 0;
static int in_packet = 0;
memcpy(&storage[nread], data, samples*sizeof(data[0]));
nread += samples;
while(nread >= speex_frame_samples)
{
static short dest[1000];
char buffer[2000];
int nb;
recv_output();
emit_frame();
speex_echo_cancellation(echo_state, storage, obuffer, dest);
printf("Encoding one frame\n");
speex_encode_int(estate, dest, &ebits);
in_packet++;
if (in_packet >= 1) {
nb = speex_bits_nbytes(&ebits);
/* Sending */
nb = speex_bits_write(&ebits, buffer, sizeof buffer);
printf("Sending %d bytes\n", nb);
send_frame(buffer, nb);
in_packet = 0;
/* Reset encoding bits */
speex_bits_reset(&ebits);
}
nread -= speex_frame_samples;
memmove(storage, &storage[speex_frame_samples], nread*sizeof(storage[0]));
}
}
void new_input_packet(const AVPacket *p) {
AVFrame *f = avcodec_alloc_frame();
int decoded;
int err;
f->nb_samples = speex_frame_samples;
err = avcodec_decode_audio4(dctx, f, &decoded, p);
if (err < 0)
error2("Cannot decode", err);
printf("Read packet of %d samples, %s format, %i rate\n", f->nb_samples,
av_get_sample_fmt_name(f->format), f->sample_rate);
new_for_speex((const short *) f->data[0], f->nb_samples);
avcodec_free_frame(&f);
}
void init_input() {
AVInputFormat *f = av_find_input_format("ALSA");
if (!f)
error("failed find ALSA");
estate = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
speex_bits_init(&ebits);
/* Prepare sample rate request */
AVDictionary *options = NULL;
av_dict_set(&options, "channels", "1", 0);
char *rate = (char *) av_malloc(100);
int val;
speex_encoder_ctl(estate, SPEEX_GET_SAMPLING_RATE, &val);
snprintf(rate, 100, "%d", val);
av_dict_set(&options, "sample_rate", rate, AV_DICT_DONT_STRDUP_VAL);
printf("Sample rate: %d Hz\n", val);
speex_encoder_ctl(estate, SPEEX_GET_FRAME_SIZE, &speex_frame_samples);
printf("Samples wanted by speex: %d\n", speex_frame_samples);
echo_state = speex_echo_state_init(speex_frame_samples, 1024);
int err;
err = avformat_open_input(&fctx, "default", f, &options);
if (err != 0)
error("failed open");
av_dict_free(&options);
AVCodec *c = NULL;
int nstream = av_find_best_stream(fctx, AVMEDIA_TYPE_AUDIO,
-1, -1, &c, 0);
if (nstream < 0)
error("failed best stream");
dctx = fctx->streams[nstream]->codec;
err = avcodec_open2(dctx, c, NULL);
if (err != 0)
error("failed avcodec_open2");
}
void process_input()
{
int err;
do {
AVPacket p;
av_init_packet(&p);
err = av_read_frame(fctx, &p);
if (err == 0) {
new_input_packet(&p);
av_free_packet(&p);
}
} while(err == 0);
speex_encoder_destroy(estate);
avcodec_close(dctx);
av_free(dctx);
avformat_close_input(&fctx);
}