#include #include "all.h" #include #include #include #include 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); }