- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个基本的 audiorecord-audiotrack,两个 android 设备之间的 udp 数据包语音聊天。它有效,但我的回声不好。我正在尝试使用由 JNI 移植到 android 的 Speex 来删除回声。我导入的 speex 有效,但回声消除无效。 native C 代码是:
#include <jni.h>
#include <speex/speex_echo.h>
#define FRAME_SIZE 256
#define FILTER_LENGTH 800
SpeexEchoState *echoState;
// Initialization of echo cancelation
void Java_telefonie_voip_VoIPActivity_InitEcho(JNIEnv * env, jobject jobj)
{
echoState = speex_echo_state_init(FRAME_SIZE, FILTER_LENGTH);
}
// Queue the frame to soundcard for playing (receiving)
void Java_telefonie_voip_VoIPActivity_Playback(JNIEnv * env, jobject jobj, jshortArray inputFrame)
{
speex_echo_playback(echoState, inputFrame);
}
jshortArray Java_telefonie_voip_VoIPActivity_Capture(JNIEnv * env, jobject jobj, jshortArray inputFrame)
{
jshortArray outputFrame;
speex_echo_capture(echoState, inputFrame, *&outputFrame);
return outputFrame;
}
// Destroing echo cancelation
void Java_telefonie_voip_VoIPActivity_DestroyEcho(JNIEnv * env, jobject jobj)
{
speex_echo_state_destroy(echoState);
}
以及一些重要的java代码:
native void InitEcho();
native void DestroyEcho();
native void Playback(short[] inputData); // listener/receiving
native short[] Capture(short[] inputData); // recorder/sender
static {
System.loadLibrary("speex");
}
public void Initialize ()
{
minBufferSize = 4096;
try
{
InitEcho();
}
catch (Exception e){Log.e(TAG, "jni " + e.getMessage());}
}
public void startRecording ()
{
isStreaming = true;
streamingThread = new Thread(new Runnable(){
@Override
public void run ()
{
try
{
audioRecorder = new AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRate,
channelConfig,
audioFormat,
minBufferSize*10
);
buffer = new short[minBufferSize];
audioRecorder.startRecording();
while(isStreaming)
{
sendPackets++;
minBufferSize = audioRecorder.read(buffer, 0, buffer.length);
// Echo cancelling
buffer = Capture(buffer);
// Send
dataPacket = new DatagramPacket(ShortToByteArray(buffer), buffer.length*2, receiverAddressIA, serverPort1);
dataSocket.send(dataPacket);
}
}
catch(Exception e)
{
Log.e(TAG, "2" + e.getMessage());
}
}
});
streamingThread.start();
}
public void startListen ()
{
isListening = true;
receivingThread = new Thread(new Runnable(){
@Override
public void run ()
{
try
{
audioTrack = new AudioTrack(
AudioManager.STREAM_VOICE_CALL,
sampleRate,
channelConfig,
audioFormat,
minBufferSize*10,
AudioTrack.MODE_STREAM
);
audioTrack.play();
buffer2 = new short[minBufferSize];
while (isListening)
{
receivedPackets++;
dataPacket2 = new DatagramPacket(ShortToByteArray(buffer2), buffer2.length*2);
dataSocket2.receive(dataPacket2);
// Cancel echo
Playback(buffer2);
// Queue to soundcard
audioTrack.write(buffer2, 0, minBufferSize);
}
}
catch(Exception e)
{
Log.e(TAG, "3" + e.getMessage());
}
}
});
receivingThread.start();
}
public short[] ByteToShortArray(byte[] byteArray)
{
short[] shortArray = new short[byteArray.length/2];
ByteBuffer.wrap(byteArray).order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(shortArray);
return shortArray;
}
问题是,当我启动记录器/流媒体线程时,它向我显示它发送了一个包,然后应用程序崩溃了,没有任何消息。你有什么建议或建议吗?请帮助我,因为我需要尽快完成这个项目,我已经努力工作并记录了自己,但它仍然不能很好地工作。谢谢!
编辑:我刚刚发现
// Echo cancelling
buffer = Capture(buffer);
正在触发崩溃。
最佳答案
更新:关于崩溃 - 这是由于误用 JNI。您不能将 jshortarray 视为 C 指针。您需要调用相关的JNI函数将其转换为C指针(GetShortArrayElements等)。
关于回声消除器 - 您当前使用的内部缓冲区大约为 2 帧,这对您来说可能不够用。Android 的上下文切换与 PC 不同,您可能会得到 4 个连续的播放帧 -> 4 个连续的记录帧 -> 等等。所以你会以这种方式丢帧。
此外,Android 音频流的延迟比 PC 高,因此 2 帧缓冲区不够用。您需要实现自己的缓冲并使用延迟的帧数进行播放,以便回声消除器在回放后看到其过滤器长度边界内的回声。
除此之外,分析和调试回声消除器的最佳方法是:1. 真正理解它在高层次上是如何工作的以及有什么要求——不是火箭科学,你可以在官方 Speex 文档上找到所有内容。2. 使用提供的 echo_diagnostic 工具,并在 Audacity 等工具中检查流,看看哪里出了问题。
Speex AEC 在正确使用时工作得很好,我已经使用它完成了 3 个不同的项目,所以只需纠正您的实现即可。
关于Android Speex 回声消除问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10080808/
我想播放由 Speex 编码的 *.spx 文件在网上。 但我不了解 Flash/Flex 或任何 Flash 音频编解码器。谷歌搜索了一整天,我得到了一些解决方案,即: 用 FLV 容器包装 Spe
我需要您的帮助来确定以下定点编码示例代码(取自 speex 手册)中的问题。我测试了对 160 个样本帧进行编码,然后将其解码回来,但问题是解码后的帧与原始帧完全不同(请参阅下面评论中的输出)。这可能
我有一个基本的 audiorecord-audiotrack,两个 android 设备之间的 udp 数据包语音聊天。它有效,但我的回声不好。我正在尝试使用由 JNI 移植到 android 的 S
我正在使用其 AudioRecord 和 AudioTrack 类以及通过 NDK 的 Speex 来制作一个 Android 到 Android VoIP(扬声器)应用程序来进行回声消除。我能够成功
我正在使用 Speex 对原始数据进行编码,但是在我对数据进行解码后,音频以更快的速度播放,因为它让您听起来像花栗鼠。我正在使用 NSpeex和 Silverlight 4。 8kHz Samplin
如何在iPhone中使用“speex”进行音频编码/解码?我没有在项目中添加框架。 最佳答案 这个blog entry: Compile Speex For iPhone克利夫顿·克雷格(Clifto
是否有一个模块支持在 Windows 上的 Python 2.6 中播放 Ogg/Speex(不是 Ogg/Vorbis)编码文件的音频? 最佳答案 到目前为止,VLC Python 绑定(bind)
我一直在寻找有关如何将 Speex 库的预处理器用于多声道音频的示例。 speex_preprocess_state_init() 的文档说: Creates a new preprocessing
我尝试在 Qt 5.2.0 中使用 Speex Acoustic Echo Cancellation,但只有一部分回声被移除,它仍然存在。 这是我的测试(未针对内存管理进行优化)。它录制语音,去除回声
我正在使用一个使用 speex jitterbuffer 的应用程序。发生的情况是,当连接发生很大变化时, jitter buffer 似乎会变大,结果是严重的延迟(最多 5 秒)- 基本上,似乎没有
如何使用Speex从 python 中编码/解码?有 wrapper 吗?我发现了一个旧项目pySpeex但它现在已经过时了(需要 Python 2.2)。 最佳答案 我认为从 pySpeex 开始(
我编译成功 libavcodec 与 斯皮克斯 启用。 我修改了 FFMPEG 文档中的示例,将示例音频编码为 Speex。 但结果文件无法使用 VLC Player(具有 Speex 解码器)播放。
我正在开发一个语音应用程序,我有 2 个选项 speex 和 nellymoser 。为什么我应该在 flex 应用程序中使用 speex 而不是 nellymoser。 最佳答案 这应该说清楚,fl
我一直在我们的移动应用程序中实现 VOIP。在语音编码/解码中,听说SPEEX codec对提高音质很有帮助。尽管它质量很好,但我不敢使用它,因为在 speex 文档中他们提到“Speex 不是为手机
我正在使用 JSpeex API 将 .wav 文件转换为 .spx 文件。在桌面上测试时一切都很完美;只用了 2 秒。 Android 开发人员使用相同的代码,但在他们的模拟器和手机上编码相同的文件
我正在学习如何将 JSpeex 用于 VoIP 应用程序,稍后我将出于教育目的编写该应用程序。为了尝试了解如何使用 JSpeex,我决定编写一个简单的 echo 应用程序。基本上,它从音频输入线读取输
我有一个 .wav 文件,我正在使用 JSpeex (最新版本,即 0.9.7)对其进行编码,但如果有人处理过该文件,则编码不会正确进行。 最佳答案 来自here 您可以找到以下代码片段: 当我使用不
一段时间以来,我一直在使用 gsm 编解码器进行网络音频聊天。由于“语音预测”,现在我想实现像 speex 或 iLBC 这样的 smth。据我了解,我需要数据包的时间戳。我也知道要使编解码器预测语音
我已经安装了 Speex Voice ACM Codec 1.0.1.1 编解码器,它们似乎有不同的 .wav header ,然后是这个 NSpeex(C#) 包中的 C# 代码中描述的 heade
我只是想通过麦克风录制我的声音并从扬声器中听我自己的声音,现在问题是当我听我的声音时,添加了回声,我试图通过使用 Speex 库取消/删除回声,但是没有成功。有人可以帮我吗,下面是代码: 从https
我是一名优秀的程序员,十分优秀!