//存储回音数据 void AudioInput::addEcho(const void *data, unsigned int nsamp) { while (nsamp > 0) { unsigned int left = min(nsamp, iEchoLength - iEchoFilled); if (bEchoMulti) { const unsigned int samples = left * iEchoChannels; if (eEchoFormat == SampleFloat) for (unsigned int i=0;i<samples;++i) pfEchoInput[i] = reinterpret_cast<const float *>(data)[i]; else for (unsigned int i=0;i<samples;++i) pfEchoInput[i] = static_cast<float>(reinterpret_cast<const short *>(data)[i]) * (1.0f / 32768.f); } else { imfEcho(pfEchoInput + iEchoFilled, data, left, iEchoChannels); } iEchoFilled += left; nsamp -= left; if (nsamp > 0) { if (eEchoFormat == SampleFloat) data = reinterpret_cast<const float *>(data) + left * iEchoChannels; else data = reinterpret_cast<const short *>(data) + left * iEchoChannels; } if (iEchoFilled == iEchoLength) { iEchoFilled = 0; float *ptr = srsEcho ? pfOutput : pfEchoInput; if (srsEcho) { spx_uint32_t inlen = iEchoLength; spx_uint32_t outlen = iFrameSize; speex_resampler_process_interleaved_float(srsEcho, pfEchoInput, &inlen, pfOutput, &outlen); } short *outbuff = new short[iEchoFrameSize]; const float mul = 32768.f; for (unsigned int j=0;j<iEchoFrameSize;++j) outbuff[j] = static_cast<short>(ptr[j] * mul); iJitterSeq = min(iJitterSeq+1,10000U); MutexLocker l(&qmEcho); qlEchoFrames.push_back(outbuff); } } }
void AudioInput::addEcho(const void *data, unsigned int nsamp) { while (nsamp > 0) { unsigned int left = qMin(nsamp, iEchoLength - iEchoFilled); imfEcho(pfEchoInput + iEchoFilled, data, left, iEchoChannels); iEchoFilled += left; nsamp -= left; if (nsamp > 0) { if (eEchoFormat == SampleFloat) data = reinterpret_cast<const float *>(data) + left * iEchoChannels; else data = reinterpret_cast<const short *>(data) + left * iEchoChannels; } if (iEchoFilled == iEchoLength) { iEchoFilled = 0; STACKVAR(short, outbuff, iFrameSize); float *ptr = srsEcho ? pfOutput : pfEchoInput; if (srsEcho) { spx_uint32_t inlen = iEchoLength; spx_uint32_t outlen = iFrameSize; speex_resampler_process_float(srsEcho, 0, pfEchoInput, &inlen, pfOutput, &outlen); } const float mul = 32768.f; for (int j=0;j<iFrameSize;++j) outbuff[j] = static_cast<short>(ptr[j] * mul); JitterBufferPacket jbp; jbp.data = reinterpret_cast<char *>(outbuff); jbp.len = iFrameSize * sizeof(short); jbp.timestamp = ++iJitterSeq * 10; jbp.span = 10; jbp.sequence = static_cast<unsigned short>(iJitterSeq); jbp.user_data = 0; jitter_buffer_put(jb, &jbp); } } }
void AudioInput::addEcho(const void *data, unsigned int nsamp) { while (nsamp > 0) { // Make sure we don't overrun the echo frame buffer const unsigned int left = qMin(nsamp, iEchoLength - iEchoFilled); if (bEchoMulti) { const unsigned int samples = left * iEchoChannels; if (eEchoFormat == SampleFloat) { for (unsigned int i=0;i<samples;++i) pfEchoInput[i] = reinterpret_cast<const float *>(data)[i]; } else { // 16bit PCM -> float for (unsigned int i=0;i<samples;++i) pfEchoInput[i] = static_cast<float>(reinterpret_cast<const short *>(data)[i]) * (1.0f / 32768.f); } } else { // Mix echo channels (converts 16bit PCM -> float if needed) imfEcho(pfEchoInput + iEchoFilled, data, left, iEchoChannels); } iEchoFilled += left; nsamp -= left; // If new samples are left offset data pointer to point at the first one for next iteration if (nsamp > 0) { if (eEchoFormat == SampleFloat) data = reinterpret_cast<const float *>(data) + left * iEchoChannels; else data = reinterpret_cast<const short *>(data) + left * iEchoChannels; } if (iEchoFilled == iEchoLength) { //Frame complete iEchoFilled = 0; // Resample if necessary float *ptr = srsEcho ? pfOutput : pfEchoInput; if (srsEcho) { spx_uint32_t inlen = iEchoLength; spx_uint32_t outlen = iFrameSize; speex_resampler_process_interleaved_float(srsEcho, pfEchoInput, &inlen, pfOutput, &outlen); } short *outbuff = new short[iEchoFrameSize]; // float -> 16bit PCM const float mul = 32768.f; for (unsigned int j=0;j<iEchoFrameSize;++j) outbuff[j] = static_cast<short>(ptr[j] * mul); // Push frame into the echo chancellers jitter buffer QMutexLocker l(&qmEcho); iJitterSeq = qMin(iJitterSeq + 1,10000U); qlEchoFrames.append(outbuff); } } }