Linux speex音频库-音频数据编解码

2024-09-07 04:32

本文主要是介绍Linux speex音频库-音频数据编解码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

speex音频数据编解码

  • speex简述
  • speex encoder(编码器)
  • speex decoder(解码器)
  • denoise vad (降噪,语音活性检测)

speex简述

speex官网

Speex: A Free Codec For Free Speech
Overview

Speex is an Open Source/Free Software patent-free audio compression format designed for speech. The Speex Project aims to lower the barrier of entry for voice applications by providing a free alternative to expensive proprietary speech codecs. Moreover, Speex is well-adapted to Internet applications and provides useful features that are not present in most other codecs. Finally, Speex is part of the GNU Project and is available under the revised BSD license.
The Technology

Speex is based on CELP and is designed to compress voice at bitrates ranging from 2 to 44 kbps. Some of Speex’s features include:

Narrowband (8 kHz), wideband (16 kHz), and ultra-wideband (32 kHz) compression in the same bitstream
Intensity stereo encoding
Packet loss concealment
Variable bitrate operation (VBR)
Voice Activity Detection (VAD)
Discontinuous Transmission (DTX)
Fixed-point port
Acoustic echo canceller
Noise suppression
1
2
3
4
5
6
7
8
9
Note that Speex has a number of features that are not present in other codecs, such as intensity stereo encoding, integration of multiple sampling rates in the same bitstream (embedded coding), and a VBR mode; see our comparison page for more.
Getting Involved

One of the simplest things you can do to get involved in Speex is by using it in your application; Speex is well-suited to handle VoIP, internet audio streaming, data archival (like voice mail), and audio books. Currently, LinPhone, Ekiga, and Asterisk are some of the projects currently using Speex. For a list of projects with Speex support, visit our Plugins & Software page.

If you have questions or are interested in contributing to the project, have a look at our roadmap, join our mailing list, or send us money so we can keep working on Speex. You can also contact the Project Lead, Jean-Marc Valin (though the mailing is usually the best place to ask questions).

Patches can be sent to the mailing list, and should apply on the latest master branch.

speex encoder(编码器)

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <getopt.h>#include <speex/speex.h>
#include <speex/speex_header.h>
#include <speex/speex_stereo.h>/*The frame size in hardcoded for this sample code but it doesn’t have to be*/
#define FRAME_SIZE 160
int main(int argc, char **argv)
{char *inFile;FILE *fin;short in[FRAME_SIZE];float input[FRAME_SIZE];char cbits[200];int nbBytes;if (argc < 2){printf("Usge: speexenc in.wav >> out.wav\n");exit(0);}/*Holds the state of the encoder*/void *state;/*Holds bits so they can be read and written to by the Speex routines*/SpeexBits bits;int i, tmp;/*Create a new encoder state in narrowband mode*/state = speex_encoder_init(&speex_nb_mode);/*Set the quality to 8 (15 kbps)*/tmp = 8;speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);inFile = argv[1];fin = fopen(inFile, "r");if(!fin){printf("open file error.\n");}/*Initialization of the structure that holds the bits*/speex_bits_init(&bits);while (1){/*Read a 16 bits/sample audio frame*/fread(in, sizeof(short), FRAME_SIZE, fin);if(feof(fin))break;/*Copy the 16 bits values to float so Speex can work on them*/for (int i=0; i<FRAME_SIZE; i++){input[i] = in[i];}/*Flush all the bits in the struct so we can encode a new frame*/speex_bits_reset(&bits);/*Encode the frame*/speex_encode(state, input, &bits);/*Copy the bits to an array of char that can be written*/nbBytes = speex_bits_write(&bits, cbits, 200);/*Write the size of the frame first. This is what sampledec expects butit’s likely to be different in your own application*/fwrite(&nbBytes, sizeof(int), 1, stdout);/*Write the compressed data*/fwrite(cbits, 1, nbBytes, stdout);}/*Destroy the encoder state*/speex_encoder_destroy(state);/*Destroy the bit-packing struct*/speex_bits_destroy(&bits);fclose(fin);return 0;}

gcc speexenc.c -o speexenc -lspeex
./speexenc in.wav >> out.wav

speex decoder(解码器)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <speex/speex.h>/*The frame size in hardcoded for this sample code but it doesn’t have to be*/
#define FRAME_SIZE 160int main(int argc, char **argv)
{char *outFile;char *inFile;FILE *fout;FILE *fin;/*Holds the audio that will be written to file (16 bits per sample)*/short out[FRAME_SIZE];/*Speex handle samples as float, so we need an array of floats*/float output[FRAME_SIZE];char cbits[200];int nbBytes;/*Holds the state of the decoder*/void *state;/*Holds bits so they can be read and written to by the Speex routines*/SpeexBits bits;int i, tmp;/*Create a new decoder state in narrowband mode*/state = speex_decoder_init(&speex_nb_mode);/*Set the perceptual enhancement on*/   tmp = 1;speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);outFile = argv[1];fout = fopen(outFile, "w");if (!fout){printf("open out file error\n");}inFile = argv[2];fin = fopen(inFile, "r");if (!fin){printf("open in file error\n");}/*Initialization of the structure that holds the bits*/speex_bits_init(&bits);while (1){/*Read the size encoded by sampleenc, this part will likely be different in your application*/fread(&nbBytes, sizeof(int), 1, fin);fprintf(stderr, "nbBytes: %d\n", nbBytes);if(feof(fin)){break;}/*Read the "packet" encoded by sampleenc*/fread(cbits, 1, nbBytes, fin);/*Copy the data into the bit-stream struct*/speex_bits_read_from(&bits, cbits, nbBytes);/*Decode the data*/speex_decode(state, &bits, output);/*Copy from float to short (16 bits) for output*/for (i=0;i<FRAME_SIZE;i++)out[i]=output[i];/*Write the decoded audio to file*/fwrite(out, sizeof(short), FRAME_SIZE, fout);}/*Destroy the decoder state*/speex_decoder_destroy(state);/*Destroy the bit-stream truct*/speex_bits_destroy(&bits);fclose(fout);return 0;
}

gcc speexdnc.c -o speexdnc -lspeex
./speexdnc new.wav out.wav

denoise vad (降噪,语音活性检测)

VAD:语音活性检测 (Voice activity detection)


#include <speex/speex.h>
#include <speex/speex_preprocess.h>
#include <stdio.h>
#include <ogg/ogg.h>#define FRAME_SIZE 1152
#define FRAME_SAMPLERATE 32000
#define DENOISE_DB (-20)int main(int argn, char* argv[]) 
{char* szInFilename = NULL;char* szOutFilename = NULL;FILE* pInFileHandle = NULL;FILE* pOutFileHandle = NULL;short in[FRAME_SAMPLERATE];int i;SpeexPreprocessState *st;int count=0;float f;printf("starting....\r\n");if(argn != 3){printf("please input 2 parameters\r\n");return -1;}szInFilename = argv[1];szOutFilename = argv[2];pInFileHandle = fopen(szInFilename, "rb");if(!pInFileHandle){printf("open file %s error\r\n", szInFilename);return -2;}pOutFileHandle = fopen(szOutFilename, "wb");if(!pOutFileHandle){printf("open file %s error\r\n", szOutFilename);fclose(pInFileHandle);return -3;}st = speex_preprocess_state_init(FRAME_SIZE, FRAME_SAMPLERATE);int denoise = 1;int noiseSuppress = DENOISE_DB;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &denoise); //降噪speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); //设置噪声的dBi=0;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);i=8000;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);i=0;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);f=.0;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);f=.0;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);int vad = 1;int vadProbStart = 80;int vadProbContinue = 65;speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_VAD, &vad); //静音检测speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START , &vadProbStart); //Set probability required for the VAD to go from silence to voicespeex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue); //Set probability required for the VAD to stay in the voice state (integer percent)while (1){int vad;int iLen = fread(in, sizeof(short), FRAME_SIZE, pInFileHandle);if(iLen <= 0){break;}if (feof(pInFileHandle))break;vad = speex_preprocess_run(st, in);if(vad != 0){printf("speech.\r\n");fwrite(in, sizeof(short), FRAME_SIZE, pOutFileHandle);}else{printf("slience---------\r\n");fwrite(in, sizeof(short), FRAME_SIZE, pOutFileHandle);}count++;}speex_preprocess_state_destroy(st);fclose(pInFileHandle);fclose(pOutFileHandle);return 0;
}

这篇关于Linux speex音频库-音频数据编解码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144059

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境