AudioInput::~AudioInput() { bRunning = false; wait(); speex_bits_destroy(&sbBits); speex_encoder_destroy(esEncState); mumble_drft_clear(&fftTable); jitter_buffer_destroy(jb); if (sppPreprocess) speex_preprocess_state_destroy(sppPreprocess); if (sesEcho) speex_echo_state_destroy(sesEcho); if (srsMic) speex_resampler_destroy(srsMic); if (srsEcho) speex_resampler_destroy(srsEcho); delete [] psMic; delete [] psSpeaker; delete [] psClean; if (pfMicInput) delete [] pfMicInput; if (pfEchoInput) delete [] pfEchoInput; if (pfOutput) delete [] pfOutput; }
void AudioEchoWidget::paintGL() { AudioInputPtr ai = g.ai; if (! ai || ! ai->sesEcho) return; ai->qmSpeex.lock(); spx_int32_t sz; speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE, &sz); STACKVAR(spx_int32_t, w, sz); STACKVAR(float, W, sz); speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE, w); ai->qmSpeex.unlock(); int N = 160; int n = 2 * N; int M = sz / n; drft_lookup d; mumble_drft_init(&d, n); for (int j=0;j<M;j++) { for (int i=0;i<n;i++) W[j*n+i] = static_cast<float>(w[j*n+i]) / static_cast<float>(n); mumble_drft_forward(&d, & W[j*n]); } mumble_drft_clear(&d); float xscale = 1.0f / static_cast<float>(N); float yscale = 1.0f / static_cast<float>(M); glBegin(GL_QUADS); for (int j = 0; j < M; j++) { for (int i=1;i < N; i++) { float xa = static_cast<float>(i) * xscale; float ya = static_cast<float>(j) * yscale; float xb = xa + xscale; float yb = ya + yscale; mapEchoToColor(sqrtf(W[j*n+2*i]*W[j*n+2*i]+W[j*n+2*i-1]*W[j*n+2*i-1]) / 65536.f); glVertex2f(xa, ya); glVertex2f(xb, ya); glVertex2f(xb, yb); glVertex2f(xa, yb); } } glEnd(); glBegin(GL_LINE_STRIP); glColor3f(1.0f, 0.0f, 1.0f); xscale = 1.0f / (2.0f*static_cast<float>(n)); yscale = 1.0f / (200.0f * 32767.0f); for (int i=0;i<2*n;i++) { glVertex2f(static_cast<float>(i)*xscale, 0.5f + static_cast<float>(w[i]) * yscale); } glEnd(); }
void AudioEchoWidget::paintEvent(QPaintEvent *) { QPainter paint(this); paint.scale(width(), height()); paint.fillRect(rect(), Qt::black); AudioInputPtr ai = g.ai; if (! ai || ! ai->sesEcho) return; ai->qmSpeex.lock(); spx_int32_t sz; speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE, &sz); STACKVAR(spx_int32_t, w, sz); STACKVAR(float, W, sz); speex_echo_ctl(ai->sesEcho, SPEEX_ECHO_GET_IMPULSE_RESPONSE, w); ai->qmSpeex.unlock(); int N = 160; int n = 2 * N; int M = sz / n; drft_lookup d; mumble_drft_init(&d, n); for (int j=0;j<M;j++) { for (int i=0;i<n;i++) W[j*n+i] = static_cast<float>(w[j*n+i]) / static_cast<float>(n); mumble_drft_forward(&d, & W[j*n]); } mumble_drft_clear(&d); float xscale = 1.0f / static_cast<float>(N); float yscale = 1.0f / static_cast<float>(M); for (int j = 0; j < M; j++) { for (int i=1;i < N; i++) { float xa = static_cast<float>(i) * xscale; float ya = static_cast<float>(j) * yscale; float xb = xa + xscale; float yb = ya + yscale; const QColor &c = mapEchoToColor(sqrtf(W[j*n+2*i]*W[j*n+2*i]+W[j*n+2*i-1]*W[j*n+2*i-1]) / 65536.f); paint.fillRect(QRectF(QPointF(xa, ya), QPointF(xb, yb)), c); } } QPolygonF poly; xscale = 1.0f / (2.0f * static_cast<float>(n)); yscale = 1.0f / (200.0f * 32767.0f); for (int i = 0; i < 2 * n; i++) { poly << QPointF(static_cast<float>(i) * xscale, 0.5f + static_cast<float>(w[i]) * yscale); } paint.setPen(QColor::fromRgbF(1.0f, 0.0f, 1.0f)); paint.drawPolyline(poly); }