/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * opusencoder.cc * * Fri Sep 19 19:21:50 CEST 2014 * Copyright 2014 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of SimpleRTP. * * SimpleRTP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * SimpleRTP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SimpleRTP; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "opusencoder.h" #include #include #include #include "samplecache.h" #define OPUS_BITRATE 64000 struct opus_encoder_private_t { OpusEncoder *ce; SampleCache *cache; }; OpusEncoder::OpusEncoder() { prv = new struct opus_encoder_private_t; prv->cache = new SampleCache(5760 * 10); int error = 0; samplerate_t srate = opus_samplerate(); prv->ce = opus_encoder_create(srate, 1/*channels()*/, OPUS_APPLICATION_AUDIO, &error); if(!prv->ce || error != OPUS_OK) { printf("srate: %d, ch: %d, Error: %d\n", srate, 1/*channels()*/, error); //throw InitException(); } // 500 to 512000 opus_encoder_ctl(prv->ce, OPUS_SET_BITRATE(OPUS_BITRATE/*bitrate()*/)); // [0-10] with 10 representing the highest complexity. opus_encoder_ctl(prv->ce, OPUS_SET_COMPLEXITY(10)); /* printf("Encoder(fs: %d, ch: %d, bitrate: %d)\n", srate, channels(), bitrate()); */ } OpusEncoder::~OpusEncoder() { if(prv) { if(prv->ce) opus_encoder_destroy(prv->ce); if(prv->cache) delete prv->cache; delete prv; } } unsigned int OpusEncoder::framesize() { return opus_samplerate() / 1000 * OPUS_FRAME_SIZE; // 10ms audio data } samplerate_t OpusEncoder::opus_samplerate() { return 48000; } framelist_t OpusEncoder::encode(const char *pcm, size_t size) { framelist_t list; // printf("PCM size: %d\n", size); samplerate_t srate = opus_samplerate(); if(prv->ce == NULL) { //throw InitException(); printf("prv->ce == NULL\n"); } size_t bytes_per_packet = ((OPUS_BITRATE/*bitrate()*/ *framesize())/srate+4)/8; prv->cache->addSamples((short*)pcm, size / sizeof(short)); //size_t p = 0; opus_int16 *samples = new opus_int16[framesize()]; while(prv->cache->cacheSize() >= framesize()) { size_t sz = prv->cache->getSamples(samples, framesize()); Frame *frame = new Frame(bytes_per_packet); int n = opus_encode(prv->ce, samples, sz / 1/*channels()*//*sizeof(short)*/, (unsigned char *)frame->data, (opus_int32)frame->size); //printf("Compressed to %d\n", n); if(n < 0) { printf("n < 0\n"); //throw EncodingException(); } frame->size = n; list.push_back(frame); } delete[] samples; //printf("%d frames in list\n", list.size()); return list; }