我正在使用Portaudio和opus在VOIP客户端上工作.我从一个帧中读取麦克风 - 使用Opus对每个帧进行编码并将其放入列表--pop列表中的第一个元素并对其进行解码 - 使用portaudio读取它
如果我在没有编码声音的情况下做同样的事情,那么效果很好.但是当我使用Opus时我的声音很糟糕,我无法理解声音(这对于voip客户端来说是不好的)
HandlerOpus::HandlerOpus(int sample_rate, int num_channels)
{
this->num_channels = num_channels;
this->enc = opus_encoder_create(sample_rate, num_channels, OPUS_APPLICATION_VOIP, &this->error);
this->dec = opus_decoder_create(sample_rate, num_channels, &this->error);
opus_int32 rate;
opus_encoder_ctl(enc, OPUS_GET_BANDWIDTH(&rate));
this->encoded_data_size = rate;
}
HandlerOpus::~HandlerOpus(void)
{
opus_encoder_destroy(this->enc);
opus_decoder_destroy(this->dec);
}
unsigned char *HandlerOpus::encodeFrame(const float *frame, int frame_size)
{
unsigned char *compressed_buffer;
int ret;
compressed_buffer = new (unsigned char[this->encoded_data_size]);
ret = opus_encode_float(this->enc, frame, frame_size, compressed_buffer, this->encoded_data_size);
return (compressed_buffer);
}
float *HandlerOpus::decodeFrame(const unsigned char *data, int frame_size)
{
int ret;
float *frame = new …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用L/R立体声生成低比特率的opus文件.什么决定是否opusenc使用L/R立体声而不是联合立体声?我有可以通过的旗帜吗?它与比特率有关吗?
opusenc input.wav output.opus //produces L/R stereo
opusenc input.wav output.opus --bitrate 8 //produces joint stereo
Run Code Online (Sandbox Code Playgroud) 我正在使用Opus for iOS(Objective-C和C++)开发Voip应用程序.
除了16000之外,它在8000,12000,24000和48000采样率下工作正常,其中应用程序在opus_encode方法上崩溃.
这是我在做的事情:
m_oAudioSession = [AVAudioSession sharedInstance];
[m_oAudioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&m_oError];
[m_oAudioSession setMode:AVAudioSessionModeVoiceChat error:&m_oError];
[m_oAudioSession setPreferredSampleRate:VOIP_AUDIO_DRIVER_DEFAULT_SAMPLE_RATE error:&m_oError];
[m_oAudioSession setPreferredInputNumberOfChannels:VOIP_AUDIO_DRIVER_DEFAULT_INPUT_CHANNELS error:&m_oError];
[m_oAudioSession setPreferredOutputNumberOfChannels:VOIP_AUDIO_DRIVER_DEFAULT_OUTPUT_CHANNELS error:&m_oError];
[m_oAudioSession setPreferredIOBufferDuration:VOIP_AUDIO_DRIVER_DEFAULT_BUFFER_DURATION error:&m_oError];
[m_oAudioSession setActive:YES error:&m_oError];
Run Code Online (Sandbox Code Playgroud)
常量:
VOIP_AUDIO_DRIVER_DEFAULT_SAMPLE_RATE is 16000
VOIP_AUDIO_DRIVER_DEFAULT_INPUT_CHANNELS is 1
VOIP_AUDIO_DRIVER_DEFAULT_OUTPUT_CHANNELS is 1
VOIP_AUDIO_DRIVER_DEFAULT_BUFFER_DURATION is 0.02
VOIP_AUDIO_DRIVER_FRAMES_PER_PACKET is 1
Run Code Online (Sandbox Code Playgroud)
之后我使用m_oAudioSession.sampleRate和m_oAudioSession.IOBufferDuration的实际采样率和缓冲持续时间.它们被设置为m_fSampleRate和m_fBufferDuration变量.
配置是:
//Describes audio component:
m_sAudioDescription.componentType = kAudioUnitType_Output;
m_sAudioDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO/*kAudioUnitSubType_RemoteIO*/;
m_sAudioDescription.componentFlags = 0;
m_sAudioDescription.componentFlagsMask = 0;
m_sAudioDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
m_sAudioFormat.mSampleRate = m_fSampleRate;
m_sAudioFormat.mFormatID = kAudioFormatLinearPCM;
m_sAudioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
m_sAudioFormat.mFramesPerPacket = VOIP_AUDIO_DRIVER_FRAMES_PER_PACKET; …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用ffmpeg库和Opus编解码器对音频帧进行编码,但我遇到了这个错误:
Resource temporarily unavailable
我的源代码:
void encode_audio(uint8_t *frame , int frame_size , void (*onPacket)(uint8_t *packet , int packet_size)){
if(audio_encoder_codec_context != NULL){
memset(audio_encoder_frame_buffer , 0 , (size_t) audio_encoder_frame_size);
swr_convert(
s16_to_flt_resampler,
&audio_encoder_frame_buffer,
audio_encoder_frame_size,
(const uint8_t **) &frame,
frame_size
);
int result = avcodec_send_frame(audio_encoder_codec_context , audio_encoder_frame);
while(result >= 0){
result = avcodec_receive_packet(audio_encoder_codec_context , audio_encoder_packet);
char *a = malloc(1024);
av_strerror(result , a , 1024);
printf("%s\n",a);
if (result == AVERROR(EAGAIN) || result == AVERROR_EOF || result < 0){
break;
}
onPacket(audio_encoder_packet->data , audio_encoder_packet->size);
av_packet_unref(audio_encoder_packet);
} …Run Code Online (Sandbox Code Playgroud) 我正在使用WebRTC从网页录制输入麦克风并通过SoX处理它.
问题是,Firefox录制的是Opus Audio格式(根据VLC媒体信息),在Ogg容器中,SoX不喜欢它:
/opt/local/bin/sox FAIL formats: can't open input file `/Users/[...]/public/audio/7a0d13a501.ogg': Input not an Ogg Vorbis audio stream
有没有办法让它与SoX一起使用?或者我应该使用另一个命令行音频工具?
我正在尝试将Opus集成到我的应用程序中,编码和解码功能返回正值,这意味着成功,但是无法播放输出音频。原始音频数据也可以播放。这是我编码数据的方式。我使用4个字节的前缀与每个数据包分开。
self.encoder = opus_encoder_create(24000, 1, OPUS_APPLICATION_VOIP, &opusError);
opus_encoder_ctl(self.encoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
- (void) encodeBufferList:(AudioBufferList *)bufferList {
BOOL success = TPCircularBufferProduceBytes(_circularBuffer, bufferList->mBuffers[0].mData, bufferList->mBuffers[0].mDataByteSize);
if (!success) {
NSLog(@"insufficient space in circular buffer!");
}
if (!_encoding) {
_encoding = YES;
dispatch_async(self.processingQueue, ^{
[self startEncodingLoop];
});
}
}
-(void)startEncodingLoop
{
int32_t availableBytes = 0;
opus_int16 *data = (opus_int16*)TPCircularBufferTail(_circularBuffer, &availableBytes);
int availableSamples = availableBytes / _inputASBD.mBytesPerFrame;
/*!
* Use dynamic duration
*/
// int validSamples[6] = {2.5, 5, 10, 20, 40, 60}; // in milisecond …Run Code Online (Sandbox Code Playgroud) 您好,我正在尝试从开放的 PortAudio 流中获取声音,使用 opus 对其进行编码,对其进行解码并使用 portaudio 再次再现它。
我这样做作为一个原型只是为了尝试和理解这个系统的机制,所以,对遵循这个具体流程没有真正的兴趣。
事实是,portaudio 在 OPUS 需要帧的地方提供了缓冲区。Mi 认为引导我在 portaudio 方面做到这一点:
err = (Pa_ReadStream(stream, readBuffer, FRAMES_PER_BUFFER));
if (err = paNoError){
qDebug()<<"Fail read";
qDebug()<<Pa_GetErrorText(err);
// blockingRecord = false;
}
while (pos<FRAMES_PER_BUFFER){
memcpy(frameBuffer,readBuffer+(pos*FRAME_SIZE*NUM_CHANNELS),FRAME_SIZE*CHANNELS);
compressedSound = om.encodeOpus(frameBuffer);
unCompressedSound = om.decodeOpus(compressedSound);
memcpy(readBuffer+(pos*FRAME_SIZE*NUM_CHANNELS),unCompressedSound,FRAME_SIZE*CHANNELS);
pos++;
}
pos = 0;
err = (Pa_WriteStream(stream, readBuffer, FRAMES_PER_BUFFER));
if (err != paNoError)
{
qDebug() << "FAIL WRITE";
qDebug()<<Pa_GetErrorText(err);
//blockingRecord = false;
}
Run Code Online (Sandbox Code Playgroud)
OPUS 方面是这样的:
unsigned char * OpusManager::encodeOpus(unsigned char *frame){
memcpy(encoded, frame, FRAME_SIZE*CHANNELS);
int ret = …Run Code Online (Sandbox Code Playgroud) 函数 opus_encode 需要帧大小作为参数。在 api doc 中它说缓冲区大小是每个通道的样本数。但是如何确定我应该使用哪个尺寸?
我在android中使用opus。采样率 16k,缓冲区大小 1280。当我在编码和解码中将帧大小设置为 640 时,解码文件的长度是原始 pcm 的一半。当我设置为 960 时,解码文件是原始 pcm 的 2/3。但设置为 1280,encode 将返回 -1 作为 arg 错误。
当我使用酷编辑播放解码时,它比原始 pcm 快。
我的参数肯定有问题。任何使用 opus 的人都可以帮助我。非常感谢。
我正在使用 Pyaudio 从麦克风捕获音频,并尝试使用 opus 编解码器对其进行编码/解码。我正在使用 SvartalF 制作的 libopus 绑定(https://github.com/svartalf/python-opus。
这是我的代码:
import pyaudio
from opus import encoder, decoder
def streaming(p):
chunk = 960
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 48000
streamin = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
input_device_index = 7,
frames_per_buffer = chunk)
streamout = p.open(format = FORMAT,
channels = CHANNELS,
rate = 48000,
output = True,
output_device_index = p.get_default_input_device_info()["index"],
frames_per_buffer = chunk)
enc = encoder.Encoder(RATE,CHANNELS,'voip')
dec = decoder.Decoder(RATE,CHANNELS)
data …Run Code Online (Sandbox Code Playgroud) 我正在捕获到Opus的实时音频流,无论我为音频采样率选择什么,都可以获得48khz的输出。
这是我的命令行
./ffmpeg -f alsa -ar 16000 -i sysdefault:CARD = CODEC -f alsa -ar 16000 -i sysdefault:CARD = CODEC_1 -filter_complex join = inputs = 2:channel_layout = stereo:map = 0.1-FR \ | 1.0- FL,setsets = expr = N / SR / TB -ar 16000 -ab 64k -c:a opus -vbr off -compression_level 5 output.ogg
这是ffmpeg的回应:
输出#0,ogg,到'output.ogg':元数据:编码器:Lavf57.48.100流#0:0:音频:opus(libopus),16000 Hz,立体声,s16,延迟104,填充0,64 kb / s (默认)元数据:编码器:Lavc57.54.100 libopus
但是,ffmpeg似乎在撒谎,因为再次分析文件时,我得到:
输入#0,ogg,来自'output.ogg':持续时间:00:00:03.21,开始:0.000000,比特率:89 kb / s流#0:0:音频:作品,48000 Hz,立体声,s16,延迟156 ,padding 0元数据:ENCODER:Lavc57.54.100 libopus
我尝试了很多采样率排列,简化为单个音频输入等-总是得到相同的结果。
有任何想法吗?