- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 cygwin 包 libwebrtc-audio-processing-devel-0.3-1 来实现来自 webrtc 的 AudioProcessing 类。
我正在使用 PortAudio 从我的麦克风读取输入,并想将其传递给 webrtc 以进行 VAD 检查,但是我不知道如何将我的数据传递给 ProcessStream 方法。
#define SAMPLE_RATE (32000)
#define FRAMES_PER_BUFFER (320)
#define PA_SAMPLE_TYPE paFloat32
#define SAMPLE_SIZE (4)
...
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
// sampleBlock should now point to 320 32 bit floats
....
apm->ProcessStream( <What goes here?> )
当我尝试像这样为第一种方法实例化 AudioFrame 时:
AudioFrame frame;
我收到以下错误:
main.cpp:161:22: error: aggregate ‘webrtc::AudioFrame frame’ has incomplete type and cannot be defined
webrtc::AudioFrame frame;
第二种和第三种方法要求数据采用“const float* const* src”格式。这是否意味着我需要一个指向常量浮点指针的常量指针?这让我有点困惑。
下面的完整例子,也是available on Pastebin ,从默认输入设备检索输入并为 ProcessStream 调用准备 webrtc。我的调用尝试包含在内并被注释掉,因为它会导致段错误。
代码需要 PortAudio 和 libwebrtc-audio-processing-devel-0.3.1。我使用以下命令在 cygwin 上编译:
g++ main_example.cpp -o main -L./ -lcygportaudio-2 -lrt -lm -pthread -I/usr/include/webrtc_audio_processing/ -DWEBRTC_WIN -std=gnu++11 -L/bin/ -lcygwebrtc_audio_processing-1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "portaudio.h"
#include <sys/time.h>
#include <windows.h>
#include <windowsx.h>
#include <unistd.h>
#include "webrtc/modules/audio_processing/include/audio_processing.h"
using webrtc::AudioProcessing;
using webrtc::AudioFrame;
using webrtc::GainControl;
using webrtc::NoiseSuppression;
using webrtc::EchoCancellation;
using webrtc::VoiceDetection;
#define SAMPLE_RATE (32000)
#define FRAMES_PER_BUFFER (320)
#define DITHER_FLAG (0)
#define PA_SAMPLE_TYPE paFloat32
#define SAMPLE_SIZE (4)
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%8f"
/*******************************************************************/
int main(int argc, char **argv);
/* error handling */
int xrun(PaStream *stream, int err, char* sampleBlock);
void error1(PaStream *stream, char* sampleBlock);
void error2(PaStream *stream, int err);
int main (int argc, char **argv)
{
PaStreamParameters inputParameters;
PaStream *stream = NULL;
PaError err;
const PaDeviceInfo* inputInfo;
char *sampleBlock = NULL;
int i;
int numBytes;
int numChannels;
err = Pa_Initialize();
if( err != paNoError ) error2(stream, err);
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputInfo = Pa_GetDeviceInfo( inputParameters.device );
numChannels = inputInfo->maxInputChannels;
inputParameters.channelCount = 1;// numChannels;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = inputInfo->defaultHighInputLatency ;
inputParameters.hostApiSpecificStreamInfo = NULL;
printf( "Input device # %d.\n", inputParameters.device );
printf( " Name: %s\n", inputInfo->name );
/* -- setup -- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) error2(stream, err);
numBytes = FRAMES_PER_BUFFER * numChannels * SAMPLE_SIZE ;
sampleBlock = (char *) malloc( numBytes );
if( sampleBlock == NULL )
{
printf("Could not allocate record array.\n");
error1(stream, sampleBlock);
}
err = Pa_StartStream( stream );
if( err != paNoError ) error1(stream, sampleBlock);
// Configure webrtc::audioprocessing
AudioProcessing* apm = AudioProcessing::Create();
apm->high_pass_filter()->Enable(true);
apm->echo_cancellation()->enable_drift_compensation(false);
apm->echo_cancellation()->Enable(true);
apm->noise_suppression()->set_level(apm->noise_suppression()->kHigh);
apm->noise_suppression()->Enable(true);
apm->gain_control()->set_analog_level_limits(0, 255);
apm->gain_control()->set_mode(apm->gain_control()->kAdaptiveAnalog);
apm->gain_control()->Enable(true);
apm->voice_detection()->Enable(true);
int analog_level = apm->gain_control()->stream_analog_level();
int delay_ms = 20;
int voiceDetected = 0;
long int holdTime = 600; //milliseconds
int prevVoiceDetected = -1;
int holding = 0;
int transmitting = 0;
int prevTransmitting = -1;
struct timeval startHoldTime, currentTime, elapsedHoldTime;
while (1) {
// Read in input frames
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) xrun(stream, err, sampleBlock);
// Run webrtc vad
apm->set_stream_delay_ms(delay_ms);
apm->gain_control()->set_stream_analog_level(analog_level);
/*
// A apm->ProcessStream call is required here. The one I've tried here seg faults, probably due to those casts I don't understand
webrtc::StreamConfig inputConfig = webrtc::StreamConfig(SAMPLE_RATE, numChannels, false);
webrtc::StreamConfig outputConfig = webrtc::StreamConfig(SAMPLE_RATE, numChannels, false);
apm->ProcessStream((const float* const*)sampleBlock, inputConfig, outputConfig, (float* const*)sampleBlock);
*/
analog_level = apm->gain_control()->stream_analog_level();
voiceDetected = apm->voice_detection()->stream_has_voice();
transmitting = 0;
if (voiceDetected) {
transmitting = 1;
holding = 0;
} else if (holding) {
gettimeofday (¤tTime, NULL);
long elapsedHoldTime = (((currentTime.tv_sec - startHoldTime.tv_sec)*1000000L+currentTime.tv_usec) - startHoldTime.tv_usec)/1000;
//printf("elapsedtime: %d\n", elapsedHoldTime); fflush(stdout);
if (elapsedHoldTime > holdTime) {
//printf("completedhold\n"); fflush(stdout);
holding = 0;
} else {
//printf("holding\n"); fflush(stdout);
transmitting = 1;
}
} else if (prevVoiceDetected) {
holding = 1;
gettimeofday (&startHoldTime, NULL);
transmitting = 1;
}
prevVoiceDetected = voiceDetected;
if (prevTransmitting != transmitting) {
printf("Transmitting: %s\n", (transmitting) ? "true" : "false"); fflush(stdout);
}
prevTransmitting = transmitting;
}
printf("Wire off.\n"); fflush(stdout);
err = Pa_StopStream( stream );
if( err != paNoError ) error1(stream, sampleBlock);
free( sampleBlock );
Pa_Terminate();
return 0;
}
int xrun(PaStream *stream, int err, char* sampleBlock) {
printf("err = %d\n", err); fflush(stdout);
if( stream ) {
Pa_AbortStream( stream );
Pa_CloseStream( stream );
}
free( sampleBlock );
Pa_Terminate();
if( err & paInputOverflow )
fprintf( stderr, "Input Overflow.\n" );
if( err & paOutputUnderflow )
fprintf( stderr, "Output Underflow.\n" );
return -2;
}
void error1(PaStream *stream, char* sampleBlock) {
free( sampleBlock );
exit(-1);
}
void error2(PaStream *stream, int err) {
if( stream ) {
Pa_AbortStream( stream );
Pa_CloseStream( stream );
}
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
exit(-1);
}
最佳答案
我私下联系了@matzeri,他给我指了一个 working example在 gstreamer 中,它为我指明了正确的方向。包括 module_common_types.h,添加 WEBRTC_AUDIO_RPOCESSING_ONLY_BUILD 指令,并在 webrtc/common_types.h 中为 cygwin 修复字符串比较函数的定义,让我可以定义一个 AudioFrame,然后使用相应的 ProcessStream 调用。
这是一个在 cygwin 上使用 libwebrtc-audio-processing-devel-0.3-1 的工作示例,用于带有 PortAudio 的 VAD!
注意:我需要修改 webrtc/common_types.h 以便它应用以下定义而不是 win32 版本
#define STR_CASE_CMP(s1, s2) ::strcasecmp(s1, s2)
#define STR_NCASE_CMP(s1, s2, n) ::strncasecmp(s1, s2, n)
主要.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "portaudio.h"
#include <sys/time.h>
#include <windows.h>
#include <windowsx.h>
#include <unistd.h>
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/include/trace.h"
using webrtc::AudioProcessing;
using webrtc::AudioFrame;
using webrtc::GainControl;
using webrtc::NoiseSuppression;
using webrtc::EchoCancellation;
using webrtc::VoiceDetection;
#define SAMPLE_RATE (32000)
#define FRAMES_PER_BUFFER (320)
#define DITHER_FLAG (0)
#define PA_SAMPLE_TYPE paInt16
#define SAMPLE_SIZE (2)
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
/*******************************************************************/
int main(int argc, char **argv);
/* error handling */
int xrun(PaStream *stream, int err, char* sampleBlock);
void error1(PaStream *stream, char* sampleBlock);
void error2(PaStream *stream, int err);
int main (int argc, char **argv)
{
PaStreamParameters inputParameters;
PaStream *stream = NULL;
PaError err;
const PaDeviceInfo* inputInfo;
char *sampleBlock = NULL;
int i;
int numBytes;
int numChannels;
err = Pa_Initialize();
if( err != paNoError ) error2(stream, err);
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputInfo = Pa_GetDeviceInfo( inputParameters.device );
numChannels = inputInfo->maxInputChannels;
inputParameters.channelCount = 1;// numChannels;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = inputInfo->defaultHighInputLatency ;
inputParameters.hostApiSpecificStreamInfo = NULL;
printf( "Input device # %d.\n", inputParameters.device );
printf( " Name: %s\n", inputInfo->name );
/* -- setup -- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) error2(stream, err);
numBytes = FRAMES_PER_BUFFER * numChannels * SAMPLE_SIZE ;
sampleBlock = (char *) malloc( numBytes );
if( sampleBlock == NULL )
{
printf("Could not allocate record array.\n");
error1(stream, sampleBlock);
}
err = Pa_StartStream( stream );
if( err != paNoError ) error1(stream, sampleBlock);
// Configure webrtc::audioprocessing
AudioProcessing* apm = AudioProcessing::Create();
apm->high_pass_filter()->Enable(true);
apm->echo_cancellation()->enable_drift_compensation(false);
apm->echo_cancellation()->Enable(true);
apm->noise_suppression()->set_level(apm->noise_suppression()->kHigh);
apm->noise_suppression()->Enable(true);
apm->gain_control()->set_analog_level_limits(0, 255);
apm->gain_control()->set_mode(apm->gain_control()->kAdaptiveAnalog);
apm->gain_control()->Enable(true);
apm->voice_detection()->Enable(true);
int analog_level = apm->gain_control()->stream_analog_level();
int delay_ms = 20;
int voiceDetected = 0;
long int holdTime = 600; //milliseconds
int prevVoiceDetected = -1;
int holding = 0;
int transmitting = 0;
int prevTransmitting = -1;
struct timeval startHoldTime, currentTime, elapsedHoldTime;
int webrtcErr = 0;
while (1) {
// Read in input frames
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) xrun(stream, err, sampleBlock);
// Run webrtc vad
apm->set_stream_delay_ms(delay_ms);
apm->gain_control()->set_stream_analog_level(analog_level);
webrtc::AudioFrame frame;
frame.num_channels_ = numChannels;
frame.sample_rate_hz_ = SAMPLE_RATE;
frame.samples_per_channel_ = FRAMES_PER_BUFFER;
memcpy(frame.data_, sampleBlock, numBytes);
if ((webrtcErr = apm->ProcessStream(&frame)) < 0) {
printf("Error Code: %d\n", webrtcErr); fflush(stdout);
return -1;
}
analog_level = apm->gain_control()->stream_analog_level();
voiceDetected = apm->voice_detection()->stream_has_voice();
transmitting = 0;
if (voiceDetected) {
transmitting = 1;
holding = 0;
} else if (holding) {
gettimeofday (¤tTime, NULL);
long elapsedHoldTime = (((currentTime.tv_sec - startHoldTime.tv_sec)*1000000L+currentTime.tv_usec) - startHoldTime.tv_usec)/1000;
//printf("elapsedtime: %d\n", elapsedHoldTime); fflush(stdout);
if (elapsedHoldTime > holdTime) {
//printf("completedhold\n"); fflush(stdout);
holding = 0;
} else {
//printf("holding\n"); fflush(stdout);
transmitting = 1;
}
} else if (prevVoiceDetected) {
holding = 1;
gettimeofday (&startHoldTime, NULL);
transmitting = 1;
}
prevVoiceDetected = voiceDetected;
if (prevTransmitting != transmitting) {
printf("Transmitting: %s\n", (transmitting) ? "true" : "false"); fflush(stdout);
}
prevTransmitting = transmitting;
}
printf("Wire off.\n"); fflush(stdout);
err = Pa_StopStream( stream );
if( err != paNoError ) error1(stream, sampleBlock);
free( sampleBlock );
Pa_Terminate();
return 0;
}
int xrun(PaStream *stream, int err, char* sampleBlock) {
printf("err = %d\n", err); fflush(stdout);
if( stream ) {
Pa_AbortStream( stream );
Pa_CloseStream( stream );
}
free( sampleBlock );
Pa_Terminate();
if( err & paInputOverflow )
fprintf( stderr, "Input Overflow.\n" );
if( err & paOutputUnderflow )
fprintf( stderr, "Output Underflow.\n" );
return -2;
}
void error1(PaStream *stream, char* sampleBlock) {
free( sampleBlock );
exit(-1);
}
void error2(PaStream *stream, int err) {
if( stream ) {
Pa_AbortStream( stream );
Pa_CloseStream( stream );
}
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
exit(-1);
}
编译:
g++ main.cpp -o main -L./ -lcygportaudio-2 -lrt -lm -pthread -L./cygspeexdsp-1 -I/usr/include/webrtc_audio_processing/ -DWEBRTC_WIN -DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD -std=gnu++11 -L/bin/ -lcygwebrtc_audio_processing-1
关于c++ - 将输入流从 PortAudio 馈送到 webrtc::AudioProcessing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42609432/
我有一个测试即将进行,我想澄清两个有关参数的问题。 在我的笔记中指出,将参数传递给函数的推荐方法是使用“按引用传递” const type& x; // for "in" parameters
当我通过 OMG 2.5(Beta)推广的 UML 规范阅读以下概念时: in: Indicates that Parameter values are passed in by the caller
我试图在用户按下 Enter 时触发一个函数。我将此输入设置为只读的原因是限制用户在填充值后修改输入中的值。 该值来自将在点击属性中触发的弹出窗口。问题是 keyup.enter 没有触发该输入。 代
我在jQuery中使用模式弹出窗口控件,该弹出窗口具有由jQuery Tokenize输入插件提供动力的输入文本。问题是,当我在模式弹出文本框中键入内容时, token 化插件的搜索结果显示为隐藏在弹
我有一个问题。当我选中复选框时,系统工作正常,总值发生变化,但一旦我修改文本输入,它就会变为 0。我需要将此文本框输入排除在更改值之外。 这是 html: $15000 $
我正在努力让它发挥作用,但还是有些不对劲。 我想用 CSS 设置提交按钮的样式以匹配我已有的按钮。 风格: input[type="button"], input[type="submit"], b
import java.util.*;; public class selection { Scanner in=new Scanner(System.in); private
这可能是一个非常菜鸟的问题。假设我有一个带宽限制为 100MB/s 的网卡,那么输入/输出带宽是否有可能达到该限制 同时 ?或者我会在任何时候遇到这个不等式:in bandwidth + out ba
看着这个问题,Fill immutable map with for loop upon creation ,我很好奇是什么this表示在 Map(1 -> this) . scala> Map(1
我有这样的东西 一个 乙 问? 是或否 数字 数字或零 我想做的是: 如果 B1 = “Y”,则让用户在 B2 中输入一个数字。 如果 B1 = “N”,则将 B2 中的值更改为零,并且不允许用户在
我有一个包含许多列的表,我想添加 input标题单元格内的字段,但我希望输入适合根据正文内容的宽度。 这是没有 input 的样子领域: 这就是 input 的样子领域: 可以看出,像“index”和
关于为 FTP 客户端设置传出和传入文件夹,您遵循哪些最佳实践(如果有)?我们通常使用“outgoing”和“incoming”,但无论你如何表述方向,它都可以有两种解释方式,具体取决于名称相对于哪一
我正在尝试“求解”给定 d 的 Pell 方程:x^2 - d * y^2 = 1,或者至少我想得到最小的 x > 0 来求解方程。到目前为止,一切都很好。这是我的 Haskell 代码 minX :
我是VS Code的新手,可以使用Ctrl + Enter将代码运行到python交互式窗口中。我希望光标自动移动到下一行,因此我可以逐行浏览代码。 能做到吗? 最佳答案 如this blog pos
我正在创建一个 bool 值矩阵/二维数组,并且我想为 dategrid 推断一种不仅仅是“ANY”的类型。 let yearRange = [2000,2001,2002,2003,2004]; l
我有两个排序的列表,例如 a = [1, 4, 7, 8] b = [1, 2, 3, 4, 5, 6] 我想知道a中的每个项目是否在b中。对于上面的示例,我想找到 a_in_b = [True, T
菜鸟警报 这很奇怪 - 当我编写以下代码时,尝试在 AngularJS 中创建自定义指令: myModule.directive('myTab', function(){ console.lo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
假设我正在使用 gdscript 静态类型,并且对于一个函数参数,我事先不知道我会得到什么。这就是 python 中 typing.Any 的作用。如何使用 gdscript 做到这一点? 似乎 Va
我使用 dropzone 上传多个图像,并且工作正常,直到我想为每个图像插入品牌和网址。 我遇到的唯一问题是,当我要从输入字段获取值时,我会从服务器获取来自字段(品牌、网址)的未定义值,但如果我使用静
我是一名优秀的程序员,十分优秀!