
nway_buffer新版,自动降噪、自动增益、自动VAD、自动录音
之前因为某些应用的需求,把fs_buffer改了下,后来就增加的功能点越来越多,《nway_buffer,一个用于缓存音视频流的buffer以及降噪、自动增益、自动vad的windows及linux库》。现在新的版本更新了,不再显式vad,不再显式降噪,不再显示增益,都由库自身完成。
调用demo:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <process.h>
#include "../nway_utils.h"
nway_buffer_t* thread_buffer; //全局的buffer,从read中读取,从write中写入
int is_read; //全局变量,用于标明是否读完了,读完了,那么在延时一个时间后,就可以走退出流程了
int read_buffer_size = 320;
int write_buffer_size = 320;
int timeout = 20;//20 second
int read_timeout = 20;//20 milisecond
int max_buffer_size = 1024 * 512;
//sem_t semLock; //用于访问is_read
HANDLE hIOMutex;// = CreateMutex(NULL, FALSE, NULL);
void ReadFunc(void* args)
{
char* data = NULL;
data = (char*)malloc(1000* sizeof(char));
int read_len = 0;
if (!data) {
printf("create data buffer error!\r\n");
WaitForSingleObject(hIOMutex, INFINITE);
is_read = 1;
ReleaseMutex(hIOMutex);
return;
}
FILE* fpRead = (FILE*)args;
while (1)
{
memset(data, 0, 1000);
read_len = fread(data,sizeof(char), read_buffer_size, fpRead);
if (read_len < 1) {
printf("read the end ,exit read thread\r\n");
break;
}
nway_buffer_lock(thread_buffer);
nway_buffer_write(thread_buffer, data, read_len);
nway_buffer_unlock(thread_buffer);
printf("%s %d read len:%d \r\n", __FUNCTION__, __LINE__, read_len);
Sleep(20);
}
printf("read from file is successed\r\n");
WaitForSingleObject(hIOMutex, INFINITE);
is_read = 1;
ReleaseMutex(hIOMutex);
nway_safe_free(data);
}
void WriteFunc(void* args)
{
char* data = NULL;
data = (char*)malloc(1000);
int read_len = 0;
int inuse = 0;
if (!data) {
printf("create write data buffer error!\r\n");
WaitForSingleObject(hIOMutex, INFINITE);
is_read = 1;
ReleaseMutex(hIOMutex);
return;
}
FILE* fpWrite = (FILE*)args;
while (!feof(fpWrite))
{
memset(data, 0, 1000);
nway_buffer_lock(thread_buffer);
if (thread_buffer == NULL) {
//nway_buffer_unlock(thread_buffer);
printf("exited write thread \r\n");
break;
}
inuse = nway_buffer_inuse(thread_buffer);
if (inuse < 1) {
nway_buffer_unlock(thread_buffer);
printf("inuse less than %d ,continue\r\n", 1);
Sleep(20);
continue;
}
read_len = nway_buffer_read(thread_buffer, data, write_buffer_size);
nway_buffer_unlock(thread_buffer);
if (read_len > 0) {
printf("%s %d write len:%d \r\n", __FUNCTION__, __LINE__, read_len);
fwrite(data, 1, read_len, fpWrite);
}
}
printf("write itno file is successed\r\n");
nway_safe_free(data);
}
int mycallback(int flag,const char* record_file,...){
if (flag == 1)
printf("this vad file:%s\n",record_file);
else
printf("this not a vad file\n");
}
int main(int argc,char *argv[])
{
FILE* fin = NULL, * fout = NULL;
printf("this is test program\r\n");
char* inputfile = NULL;// = strdup(argv[1]);
char* outputfile = NULL;// strdup(argv[2]);
if (argc < 3) {
printf("usage: demo.exe in.wav out.wav\r\n");
//return -1;
inputfile = strdup("d:\\microsip.exe");
outputfile = strdup("d:\\nwaysip.exe");
}else{
inputfile = strdup(argv[1]);
outputfile = strdup(argv[2]);
}
fin = fopen(inputfile, "r");
if (fin == NULL) {
printf("open input file failed\r\n");
return -1;
}
fout = fopen(outputfile, "wb+");
if (fout == NULL) {
printf("open outfile failed\r\n");
return -1;
}
fseek(fin, 0, SEEK_END);
int file_size = ftell(fin);
printf("this program use multi thread to read file from %s ,len:%d,then write into %s\r\n", inputfile, file_size,outputfile);
rewind(fin);
// sem_init(&semLock, 0, 1);
nway_buffer_create_dynamic(&thread_buffer, max_buffer_size, 1024 * 64, 0);
nway_use_vad(thread_buffer);//设定使用vad
nway_set_callback(thread_buffer,mycallback);
nway_set_record_path(thread_buffer,"./");
is_read = 0;
HANDLE hIOMutex = CreateMutex(NULL, FALSE, NULL);
_beginthread(ReadFunc, 0, fin);
_beginthread(WriteFunc, 0, fout);
while (1) {
WaitForSingleObject(hIOMutex, INFINITE);
if (is_read == 1) {
ReleaseMutex(hIOMutex);
Sleep(timeout * 1000);
break;
}
ReleaseMutex(hIOMutex);
Sleep(20);
}
CloseHandle(hIOMutex);
nway_buffer_destroy(&thread_buffer);
if (inputfile) nway_safe_free(inputfile);
if (outputfile) nway_safe_free(outputfile);
fclose(fin);
fclose(fout);
}
库头文件:
#ifndef NWAY_BUFFER_H
#define NWAY_BUFFER_H
#include "nway_buffer_define.h"
NWAY_BEGIN_EXTERN_C
/**
* @defgroup nway_buffer Buffer Routines
* @ingroup core1
* The purpose of this module is to make a plain buffering interface that can be used for read/write buffers
* throughout the application. The first implementation was done to provide the functionality and the interface
* and I think it can be optimized under the hood as we go using bucket brigades and/or ring buffering techniques.
* @{
*/
//typedef struct apr_pool_t nway_memory_pool_t;
//typedef nway_buffer ;
nway_status_t
nway_buffer_create_partition(nway_memory_pool_t *pool, nway_buffer_t **buffer, void *data, nway_size_t datalen);
nway_status_t
nway_buffer_set_partition_data(nway_buffer_t *buffer, void *data, nway_size_t datalen);
nway_status_t
nway_buffer_reset_partition_data(nway_buffer_t *buffer);
/*! \brief Allocate a new nway_buffer
* \param pool Pool to allocate the buffer from
* \param buffer returned pointer to the new buffer
* \param max_len length required by the buffer
* \return status
*/
nway_status_t
nway_buffer_create(_In_ nway_memory_pool_t *pool, _Out_ nway_buffer_t **buffer, _In_ nway_size_t max_len);
/*! \brief Allocate a new dynamic nway_buffer
* \param buffer returned pointer to the new buffer
* \param blocksize length to realloc by as data is added
* \param start_len ammount of memory to reserve initially
* \param max_len length the buffer is allowed to grow to
* \return status
*/
nway_status_t nway_buffer_create_dynamic(_Out_ nway_buffer_t **buffer, _In_ nway_size_t blocksize, _In_ nway_size_t start_len,
_In_ nway_size_t max_len);
nway_status_t nway_mutex_create(NWAY_HANDLE *mymutex);
void nway_buffer_add_mutex(_In_ nway_buffer_t *buffer, _In_ NWAY_HANDLE *mutex);
void nway_buffer_lock(_In_ nway_buffer_t *buffer);
nway_status_t nway_buffer_trylock(_In_ nway_buffer_t *buffer);
void nway_buffer_unlock(_In_ nway_buffer_t *buffer);
/*! \brief Get the length of a nway_buffer_t
* \param buffer any buffer of type nway_buffer_t
* \return int size of the buffer.
*/
nway_size_t
nway_buffer_len(_In_ nway_buffer_t *buffer);
/*! \brief Get the freespace of a nway_buffer_t
* \param buffer any buffer of type nway_buffer_t
* \return int freespace in the buffer.
*/
nway_size_t
nway_buffer_freespace(_In_ nway_buffer_t *buffer);
/*! \brief Get the in use amount of a nway_buffer_t
* \param buffer any buffer of type nway_buffer_t
* \return int ammount of buffer curently in use
*/
nway_size_t
nway_buffer_inuse(_In_ nway_buffer_t *buffer);
/*! \brief Read data from a nway_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer.
* \param buffer any buffer of type nway_buffer_t
* \param data pointer to the read data to be returned
* \param datalen amount of data to be returned
* \return int ammount of data actually read
*/
nway_size_t
nway_buffer_read(_In_ nway_buffer_t *buffer, _In_ void *data, _In_ nway_size_t datalen);
/*! \brief Read data from a nway_buffer_t up to the ammount of datalen if it is available, without removing read data from buffer.
* \param buffer any buffer of type nway_buffer_t
* \param data pointer to the read data to be returned
* \param datalen amount of data to be returned
* \return int ammount of data actually read
*/
nway_size_t
nway_buffer_peek(_In_ nway_buffer_t *buffer, _In_ void *data, _In_ nway_size_t datalen);
nway_size_t
nway_buffer_peek_zerocopy(_In_ nway_buffer_t *buffer, _Out_ const void **ptr);
/*! \brief Read data endlessly from a nway_buffer_t
* \param buffer any buffer of type nway_buffer_t
* \param data pointer to the read data to be returned
* \param datalen amount of data to be returned
* \return int ammount of data actually read
* \note Once you have read all the data from the buffer it will loop around.
*/
nway_size_t
nway_buffer_read_loop(_In_ nway_buffer_t *buffer, _In_ void *data, _In_ nway_size_t datalen);
/*! \brief Assign a number of loops to read
* \param buffer any buffer of type nway_buffer_t
* \param loops the number of loops (-1 for infinite)
*/
void nway_buffer_set_loops(_In_ nway_buffer_t *buffer, _In_ int32_t loops);
/*! \brief Write data into a nway_buffer_t up to the length of datalen
* \param buffer any buffer of type nway_buffer_t
* \param data pointer to the data to be written
* \param datalen amount of data to be written
* \return int amount of buffer used after the write, or 0 if no space available
*/
nway_size_t
nway_buffer_write(_In_ nway_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ nway_size_t datalen);
/*! \brief Remove data from the buffer
* \param buffer any buffer of type nway_buffer_t
* \param datalen amount of data to be removed
* \return int size of buffer, or 0 if unable to toss that much data
*/
nway_size_t
nway_buffer_toss(_In_ nway_buffer_t *buffer, _In_ nway_size_t datalen);
/*! \brief Remove all data from the buffer
* \param buffer any buffer of type nway_buffer_t
*/
void nway_buffer_zero(_In_ nway_buffer_t *buffer);
nway_size_t
nway_buffer_slide_write(nway_buffer_t *buffer, const void *data, nway_size_t datalen);
/*! \brief Destroy the buffer
* \param buffer buffer to destroy
* \note only neccessary on dynamic buffers (noop on pooled ones)
*/
void nway_buffer_destroy(nway_buffer_t **buffer);
nway_size_t
nway_buffer_zwrite(_In_ nway_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ nway_size_t datalen);
void *
nway_buffer_get_head_pointer(nway_buffer_t *buffer);
void *nway_core_alloc(nway_memory_pool_t *pool, nway_size_t memory);
#define nway_assert(expr) \
do \
{ \
if (!(expr)) \
{ \
fprintf(stderr, "MEMERR\n"); \
abort(); \
} \
} while (0)
void nway_safe_free(void *p);
/// @brief /
/// @param buffer
void nway_use_vad(_In_ nway_buffer_t *buffer);
void nway_unuse_vad(_In_ nway_buffer_t *buffer);
void nway_set_record_path(_In_ nway_buffer_t *buffer,_In_ const char* record_path);
/// @brief 设置回调函数,一个变量只声明一次
/// @param buffer
/// @param callback
void nway_set_callback(_In_ nway_buffer_t *buffer,buffer_callback callback);
/// @brief 自动生成当前要进行vad的录音文件路径和名称,结合record_path
/// @param buffer
/// @return
char* nway_gen_record_file(_In_ nway_buffer_t *buffer);
/// @brief 设置要进行vad的参数
/// @param buffer
/// @param min_speak_tm
/// @param max_record_tm
/// @param max_wait_tm
/// @param min_pause_tm
/// @param auto_gain
void nway_set_vad_params(_In_ nway_buffer_t *buffer,uint32_t min_speak_tm,uint32_t max_record_tm,
uint32_t max_wait_tm,uint32_t min_pause_tm,uint32_t auto_gain);
/// @brief 设置要进行完整的录音文件路径,会自动设置auto_record 为1
/// @param buffer
/// @param full_record_file 由外部应用传进的完整路径和文件名
void nway_set_full_record_file(_In_ nway_buffer_t *buffer,const char* full_record_file);
///////////////////////////////////////////////////////////////////////////////
NWAY_END_EXTERN_C
#endif