语音识别之端点检测

2023-11-16

      在之前呢我们已经把portaudio平台搭好了,可以采集声音信号并播放了。那么接下来呢我们就来做一些实质性的东西——自适应端点检测。那么什么是自适应端点检测呢?也就是采集声音信号的时候,开始说话到说话结束,我们把这一段声音信号采集下来进行处理。不然那么多信号都去处理,没有声音也处理那就浪费了很多的空间以及浪费了CPU去做后续的操作。后面的功夫是省了,但是前面的工作就多了。天下可没有白费的午餐!接下来我就大概说一下我的做法吧。


1、基础


      采样频率的设置:我们人耳一般可以听到的频率最高就是16000HZ。根据采样定理,一般采样频率要是这个的两倍才不会发生混叠。所以我们在通话的时候采样频率一般是8Khz,带宽就需要16Khz。这样就基本可以使得通话的体验非常到位,还原度非常高!不是说采样频率越高声音的效果就越好,这是一个trade-off。这一次我们采样就用16Khz,这样其实已经可以把基本的声音采下来。因为人耳对于低频还是更加敏感!现在的高保真就是44.1Khz的采样率。在经过量化(均匀量化和非均匀量化)就可以进行保存。怎么把采集到的信号进行数字化变成非均匀量化比如Mu律。请参考:

http://www.speech.cs.cmu.edu/comp.speech/Section2/Q2.7.html

         声音采集时遇到的问题:在进行声音采集的时候有噪声,我们得小减小噪声的影响;以及还有回声。

        声音采集的方式:直接对已有的声音(已经录制好的)进行处理;以及现场录制。这样的工具有:Windows recorder,Adobe audition,Linux的arecord。

        声音保存的方式:如下图。一般是PCM之后才好做进一步的处理。

   

          声音采集时序考虑的参数:采样频率,量化方式,通道,存储。    

          声音采集时的两种模式:阻塞(自己设定时间,不管有没有数据都要回来)和回调(有有效的数据的时候才会调用这个函数返回数据),这两种在Portaudio里面都有对应的代码。在这里你大概也想到了我们应该使用的就是回调才能实现我们的功能。

         语言处理的模式:Push和Pull。在这里的话,这两个东西正好和阻塞和回调差不多对应。

         端点检测:实现效果如下图:一般来说人说话是突然说的,然后我们还要判断什么时候结束。

  


2、算法


具体实现的步骤如下图:


  • 判别:计算每个时刻的能量,设定一个阈值k,如果大于它,我们认为是1(1表示该点是语言),否则就是0。能量计算的公式就是:
  • 平滑:小于100ms的silien我们认为是语音的部分,大于250ms的语言我们才认为是语言。在截取的语音信号前后多截出250ms。这个的前提是比较安静,如果不安静的话那么就得另当别论,看外界影响有多大。
  • 算法一:先来一个比较简单的算法

 

  • 算法二:更复杂一些的算法

      


3、代码

捕获声音信号并转化:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>         //function log
#include <conio.h>        //kbhit()
#include "portaudio.h"
#include "readwave.h"     //WriteWave()

/* #define SAMPLE_RATE  (17932) // Test failure to open with this value. */
//SAMPLE_RATE,  FRAMES_PER_BUFFER, NUM_SECONDS, NUM_CHANNELS are modified by Yao Canwu
#define SAMPLE_RATE (16000)  
#define FRAMES_PER_BUFFER (400)
#define NUM_SECONDS     (60)
#define NUM_CHANNELS    (1)
/* #define DITHER_FLAG     (paDitherOff) */
#define DITHER_FLAG     (0) /**/
/** Set to 1 if you want to capture the recording to a file. */
#define WRITE_TO_FILE   (0)

/* Select sample format. */
#if 0
#define PA_SAMPLE_TYPE  paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE  (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#define PA_SAMPLE_TYPE  paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE  (0)
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE  paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE  (0)
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE  paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE  (128)
#define PRINTF_S_FORMAT "%d"
#endif

typedef struct
{
	int          frameIndex;  /* Index into sample array. */
	int          maxFrameIndex;
	SAMPLE      *recordedSamples;
}
paTestData;

//calculate the energy in decibe of a frame segment
//added by Yao Canwu
float energyPerSampleInDecibe(const SAMPLE *ptr)
{
	float energy = 0.0f;
	SAMPLE temp;
	for (unsigned long i = 0; i<FRAMES_PER_BUFFER; i++)
	{
		temp = *(ptr + i);
		energy += temp * temp;
	}
	energy = 10 * log(energy);
	return energy;
}
//An Adaptive Endpointing Algorithm
//added by Yao Canwu
const float forgetfactor = 1;
const float adjustment = 0.05;
//key value for classifyFrame(), need to adjust to different environment.
const float threshold = 10; //
float background = 0;
float level = 0;
int count = 0;

bool classifyFrame(const SAMPLE *ptr)
{
	float current = energyPerSampleInDecibe(ptr);
	bool isSpeech = false;
	level = ((level * forgetfactor) + current) / (forgetfactor + 1);
	if (current < background)  background = current;
	else background += (current - background) * adjustment;
	if (level < background)	level = background;
	if (level - background > threshold)	isSpeech = true;
	return isSpeech;
}
/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int recordCallback(const void *inputBuffer, void *outputBuffer,
	unsigned long framesPerBuffer,
	const PaStreamCallbackTimeInfo* timeInfo,
	PaStreamCallbackFlags statusFlags,
	void *userData)
{
	paTestData *data = (paTestData*)userData;
	const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
	SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
	long framesToCalc;
	long i;
	int finished;
	unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;

	(void)outputBuffer; /* Prevent unused variable warnings. */
	(void)timeInfo;
	(void)statusFlags;
	(void)userData;

	if (framesLeft < framesPerBuffer)
	{
		framesToCalc = framesLeft;
		finished = paComplete;
	}
	else
	{
		framesToCalc = framesPerBuffer;
		finished = paContinue;
	}

	if (inputBuffer == NULL)
	{
		for (i = 0; i<framesToCalc; i++)
		{
			*wptr++ = SAMPLE_SILENCE;  /* left */
			if (NUM_CHANNELS == 2) *wptr++ = SAMPLE_SILENCE;  /* right */
		}
	}
	else
	{
		for (i = 0; i<framesToCalc; i++)
		{
			*wptr++ = *rptr++;  /* left */
			if (NUM_CHANNELS == 2) *wptr++ = *rptr++;  /* right */
		}
	}
	data->frameIndex += framesToCalc;
	/* calculate the initial background and initial level,
	** which will be used for classify frame
	** Added by Yao Canwu
	*/
	if (data->frameIndex == 0)
	{
		level = energyPerSampleInDecibe(&data->recordedSamples[0]);
		background = 0.0f;
		SAMPLE temp;
		for (i = 0; i < 10 * framesPerBuffer; i++)
		{
			temp = data->recordedSamples[i];
			background += temp * temp;
		}
		background = log(background);
	}
	//Silence in 4 seconds means the end of audio capture
	if (classifyFrame(rptr)) count = 0;
	else count++;
	//printf("count = %d\n", count);

	if (count >= 80) data->maxFrameIndex = data->frameIndex;

	return finished;
}

/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int playCallback(const void *inputBuffer, void *outputBuffer,
	unsigned long framesPerBuffer,
	const PaStreamCallbackTimeInfo* timeInfo,
	PaStreamCallbackFlags statusFlags,
	void *userData)
{
	paTestData *data = (paTestData*)userData;
	SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
	SAMPLE *wptr = (SAMPLE*)outputBuffer;
	unsigned int i;
	int finished;
	unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;

	(void)inputBuffer; /* Prevent unused variable warnings. */
	(void)timeInfo;
	(void)statusFlags;
	(void)userData;

	if (framesLeft < framesPerBuffer)
	{
		/* final buffer... */
		for (i = 0; i<framesLeft; i++)
		{
			*wptr++ = *rptr++;  /* left */
			if (NUM_CHANNELS == 2) *wptr++ = *rptr++;  /* right */
		}
		for (; i<framesPerBuffer; i++)
		{
			*wptr++ = 0;  /* left */
			if (NUM_CHANNELS == 2) *wptr++ = 0;  /* right */
		}
		data->frameIndex += framesLeft;
		finished = paComplete;
	}
	else
	{
		for (i = 0; i<framesPerBuffer; i++)
		{
			*wptr++ = *rptr++;  /* left */
			if (NUM_CHANNELS == 2) *wptr++ = *rptr++;  /* right */
		}
		data->frameIndex += framesPerBuffer;
		finished = paContinue;
	}
	return finished;
}

/*******************************************************************/
int main(void)
{
	PaStreamParameters  inputParameters,
		outputParameters;
	PaStream*           stream;
	PaError             err = paNoError;
	paTestData          data;
	int                 i;
	int                 totalFrames;
	int                 numSamples;
	int                 numBytes;
	SAMPLE              max, val;
	double              average;

	printf("patest_record.c\n"); fflush(stdout);

	data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
	data.frameIndex = 0;
	numSamples = totalFrames * NUM_CHANNELS;
	numBytes = numSamples * sizeof(SAMPLE);
	data.recordedSamples = (SAMPLE *)malloc(numBytes); /* From now on, recordedSamples is initialised. */
	if (data.recordedSamples == NULL)
	{
		printf("Could not allocate record array.\n");
		goto done;
	}
	for (i = 0; i<numSamples; i++) data.recordedSamples[i] = 0;

	err = Pa_Initialize();
	if (err != paNoError) goto done;

	inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
	if (inputParameters.device == paNoDevice) {
		fprintf(stderr, "Error: No default input device.\n");
		goto done;
	}
	inputParameters.channelCount = 1;                    /* stereo input */
	inputParameters.sampleFormat = PA_SAMPLE_TYPE;
	inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
	inputParameters.hostApiSpecificStreamInfo = NULL;

	//set a keyboard hit to start recording. Added by Yao Canwu
	printf("Press any key to start recording\n");
	while (!kbhit()){}

	/* Record some audio. -------------------------------------------- */
	err = Pa_OpenStream(
		&stream,
		&inputParameters,
		NULL,                  /* &outputParameters, */
		SAMPLE_RATE,
		FRAMES_PER_BUFFER,
		paClipOff,      /* we won't output out of range samples so don't bother clipping them */
		recordCallback,
		&data);
	if (err != paNoError) goto done;

	err = Pa_StartStream(stream);
	if (err != paNoError) goto done;
	printf("\n=== Now start recording!!\n"); fflush(stdout);
	/* Pa_IsStreamActive: Determine whether the stream is active. A stream
	is active after a successful call to Pa_StartStream(), until it becomes
	inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(),
	or as a result of a return value other than paContinue from the stream callback.
	In the latter case, the stream is considered inactive after the last buffer has finished playing. */
	while ((err = Pa_IsStreamActive(stream)) == 1)
	{
		Pa_Sleep(1000);
		printf("index = %d\n", data.frameIndex); fflush(stdout);
	}
	if (err < 0) goto done;

	err = Pa_CloseStream(stream);
	if (err != paNoError) goto done;

	//Write wave to file in wav formate. Added by Yao Canwu
	printf("Waiting to save into file...\n");
	char *path = "audio.wav";
	WriteWave(path, data.recordedSamples, data.maxFrameIndex, SAMPLE_RATE);
	printf("Save successfully!\n");

	/* Write recorded data to a file. */
#if WRITE_TO_FILE
	{
		FILE  *fid;
		fid = fopen("recorded.raw", "wb");
		if (fid == NULL)
		{
			printf("Could not open file.");
		}
		else
		{
			fwrite(data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid);
			fclose(fid);
			printf("Wrote data to 'recorded.raw'\n");
		}
	}
#endif
	/* Playback recorded data.  -------------------------------------------- */
	data.frameIndex = 0;

	outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
	if (outputParameters.device == paNoDevice) {
		fprintf(stderr, "Error: No default output device.\n");
		goto done;
	}
	outputParameters.channelCount = 1;                     /* stereo output */
	outputParameters.sampleFormat = PA_SAMPLE_TYPE;
	outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
	outputParameters.hostApiSpecificStreamInfo = NULL;

	printf("\n=== Now playing back. ===\n"); fflush(stdout);
	err = Pa_OpenStream(
		&stream,
		NULL, /* no input */
		&outputParameters,
		SAMPLE_RATE,
		FRAMES_PER_BUFFER,
		paClipOff,      /* we won't output out of range samples so don't bother clipping them */
		playCallback,
		&data);
	if (err != paNoError) goto done;

	if (stream)
	{
		err = Pa_StartStream(stream);
		if (err != paNoError) goto done;

		printf("Waiting for playback to finish.\n"); fflush(stdout);

		while ((err = Pa_IsStreamActive(stream)) == 1) Pa_Sleep(100);
		if (err < 0) goto done;

		err = Pa_CloseStream(stream);
		if (err != paNoError) goto done;

		printf("Done.\n"); fflush(stdout);
	}
done:
	Pa_Terminate();
	if (data.recordedSamples)       /* Sure it is NULL or valid. */
		free(data.recordedSamples);
	if (err != paNoError)
	{
		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));
		err = 1;          /* Always return 0 or 1, but no other return codes. */
	}
	system("pause");
	return err;
}

readwav:

#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <assert.h>
#include <string.h>
#include "readwave.h"


bool WaveRewind(FILE *wav_file, WavFileHead *wavFileHead)
{
	char riff[8],wavefmt[8];
	short i;
	rewind(wav_file);
	fread(wavFileHead,sizeof(struct WavFileHead),1,wav_file);

	for ( i=0;i<8;i++ )
	{
		riff[i]=wavFileHead->RIFF[i];
		wavefmt[i]=wavFileHead->WAVEfmt_[i];
	}
	riff[4]='\0';
	wavefmt[7]='\0';
	if ( strcmp(riff,"RIFF")==0 && strcmp(wavefmt,"WAVEfmt")==0 )
		return	true;  // It is WAV file.
	else
	{
		rewind(wav_file);
		return(false);
	}
}


short *ReadWave(const char *wavFile, int *numSamples, int *sampleRate ) 
{                                                               
	FILE	*wavFp;
	WavFileHead		wavHead;
	short	*waveData;
	long	numRead;

	wavFp = fopen(wavFile, "rb");
	if (!wavFp)	
	{
		printf("\nERROR:can't open %s!\n", wavFile);
		exit(0);
	}

	if (WaveRewind(wavFp, &wavHead) == false)
	{
		printf("\nERROR:%s is not a Windows wave file!\n", wavFile);
		exit(0);
	}

	waveData = new short [wavHead.RawDataFileLength/sizeof(short)];
	numRead = fread(waveData, sizeof(short), wavHead.RawDataFileLength / 2, wavFp);
	assert(numRead * sizeof(short) == (unsigned long)wavHead.RawDataFileLength);
	fclose(wavFp);

	*numSamples = wavHead.RawDataFileLength/sizeof(short);
	*sampleRate = wavHead.SampleRate;
	return	waveData;
}

void FillWaveHeader(void *buffer, int raw_wave_len, int sampleRate)
{
	WavFileHead  wavHead;

	strcpy(wavHead.RIFF, "RIFF");
	strcpy(wavHead.WAVEfmt_, "WAVEfmt ");
	wavHead.FileLength = raw_wave_len + 36;
	wavHead.noUse = 16;
	wavHead.FormatCategory = 1;
	wavHead.NChannels = 1;
	wavHead.SampleRate = sampleRate;
	wavHead.SampleBytes = sampleRate*2;
	wavHead.BytesPerSample = 2;
	wavHead.NBitsPersample = 16;
	strcpy(wavHead.data, "data");
	wavHead.RawDataFileLength = raw_wave_len;

	memcpy(buffer, &wavHead, sizeof(WavFileHead));
}

void WriteWave(const char *wavFile, short *waveData, int numSamples, int sampleRate)
{
	FILE	*wavFp;
	WavFileHead		wavHead;
	long	numWrite;

	wavFp = fopen(wavFile, "wb");
	if (!wavFp)	
	{
		printf("\nERROR:can't open %s!\n", wavFile);
		exit(0);
	}

	FillWaveHeader(&wavHead, numSamples*sizeof(short), sampleRate);
	fwrite(&wavHead, sizeof(WavFileHead), 1, wavFp);
	numWrite = fwrite(waveData, sizeof(short), numSamples, wavFp);
	assert(numWrite == numSamples);
	fclose(wavFp);
}

void GetWavHeader(const char *wavFile, short *Bits, int *Rate,
				  short *Format, int *Length, short *Channels) 
{                                                               
	FILE	*wavFp;
	WavFileHead		wavHead;
	char    *waveData;
	long	numRead,File_length;

	wavFp = fopen(wavFile, "rb");
	if (!wavFp)	
	{
		printf("\nERROR:can't open %s!\n", wavFile);
		exit(0);
	}
    fseek(wavFp,0,SEEK_END);
	File_length=ftell(wavFp);

	if (WaveRewind(wavFp, &wavHead) == false)
	{
		printf("\nERROR:%s is not a Windows wave file!\n", wavFile);
		exit(0);
	}

	waveData = new char[(File_length-sizeof(struct WavFileHead))/sizeof(char)];
	numRead = fread(waveData, sizeof(char), File_length-sizeof(struct WavFileHead), wavFp);
	fclose(wavFp);

	*Bits = wavHead.NBitsPersample;
	*Format = wavHead.FormatCategory;
	*Rate = wavHead.SampleRate;
	*Length = (int)numRead;
	*Channels = wavHead.NChannels;

	delete []	waveData;
}


short *ReadWavFile(const char *wavFile, int *numSamples, int *sampleRate )
{                                                               
	FILE	*wavFp;
	WavFileHead		wavHead;
	short	*waveData;
	long	numRead,File_length;

	wavFp = fopen(wavFile, "rb");
	if (!wavFp)	
	{
		printf("\nERROR:can't open %s!\n", wavFile);
		exit(0);
	}
    fseek(wavFp,0,SEEK_END);
	File_length=ftell(wavFp);


	if (WaveRewind(wavFp, &wavHead) == false)
	{
		printf("\nERROR:%s is not a Windows wave file!\n", wavFile);
		exit(0);
	}

	waveData = new short [(File_length-sizeof(struct WavFileHead))/sizeof(short)];
	numRead = fread(waveData, sizeof(short), (File_length-sizeof(struct WavFileHead))/sizeof(short), wavFp);
	fclose(wavFp);

	*numSamples = (int)numRead;
	*sampleRate = wavHead.SampleRate;
	return	waveData;
}

void ReadWav(const char *wavFile, short *waveData, int *numSamples, int *sampleRate)
{                                                               
	FILE	*wavFp;
	WavFileHead		wavHead;
	long	numRead;

	wavFp = fopen(wavFile, "rb");
	if (!wavFp)	
	{
		printf("\nERROR:can't open %s!\n", wavFile);
		exit(0);
	}

	if (WaveRewind(wavFp, &wavHead) == false)
	{
		printf("\nERROR:%s is not a Windows PCM file!\n", wavFile);
		exit(0);
	}

	numRead = fread(waveData, sizeof(short), wavHead.RawDataFileLength/2, wavFp);
	assert(numRead*sizeof(short) == (unsigned long)wavHead.RawDataFileLength);
	fclose(wavFp);

	*numSamples = wavHead.RawDataFileLength/sizeof(short);
	*sampleRate = wavHead.SampleRate;
}



特别说明:以上截图来自于CMU的李明老师的上课PPT。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

语音识别之端点检测 的相关文章

  • 2021-09-15 C++ 继承和多态(虚函数,纯虚函数,虚继承)

    C 继承和多态 虚函数 纯虚函数 虚继承 一 继承 继承的概念 为了代码的复用 保留基类的原始结构 并添加派生类的新成员 继承的本质 代码复用 我们用下图解释下 那么我们这里就可以提出几个问题了 进程的方式有哪些呢 这里有三种继承方式 pu
  • 语音识别芯片LD3320介绍再续

    语音识别芯片LD3320驱动程序 1 芯片复位 复位就是对LD3320芯片的第47腿 RSTB 发送低电平 然后需要对片选CS做一次拉低 拉 高的操作 以激活内部DSP 按照以下顺序 void LD reset RSTB 1 delay 1
  • 上下文相关音素-状态绑定

    在发音过程中 因为协同发音的影响 同一个音素在不同的位置 其发音变化很大 如下图所示 同样的元音 eh 在不同的单词中的发音在频域上区分非常明显 因为单音素monophone 是上下文独立的 context independent 为了能够
  • Voice Control for ChatGPT 轻松实现使用语音与ChatGPT进行对话。

    缘由 日常生活中 我们与亲人朋友沟通交流一般都是喜欢语音的形式来完成的 毕竟相对于文字来说语音就不会显的那么的苍白无力 同时最大的好处就是能解放我们的双手吧 能更快实现两者间的对话 沟通便更高效了 Voice Control for Cha
  • Audacity如何改变音频节奏?Audacity调整音频节奏方法

    很多人在录完音频后都会试听效果 经常会发现音频的节奏要么太快 要么太慢 可是自己又不愿意花时间 花人力 物力再去录制音频 为了解决这问题 我们可以用Audacity改变音频的节奏 加快或者减慢某个音频片段或者整个音频的节奏 只是很多人不懂怎
  • GMM-HMM在语音识别中的应用

    1 语音识别系统的基本结构 2 涉及算法 3 GMM高斯混合模型 3 1高斯混合模型的基本概念 高斯混合模型是指具有如下形式的概率分布模型 p y k 1k k y k p y arrowvert theta sum k 1 k alpha
  • 爱好高科技之人脸识别模块

    前段时间看到一款性价比很不错的人脸识别模组 2个关键指标引起了我极大的兴趣 1 99 的识别通过率 误识率低于百万分之一 2 双目摄像头 活体检测 于是买了几个 结合离线语音模块 两者通过串口进行一问一答通信 人机交互部分通过语音和OLED
  • 混沌神经网络的实际应用,进化算法优化神经网络

    人工神经网络的发展趋势 人工神经网络特有的非线性适应性信息处理能力 克服了传统人工智能方法对于直觉 如模式 语音识别 非结构化信息处理方面的缺陷 使之在神经专家系统 模式识别 智能控制 组合优化 预测等领域得到成功应用 人工神经网络与其它传
  • 通过聚类中心进行0-9数字语音识别(matlab)——基于K-means聚类

    项目已免费开源 https gitee com zhengzsj automatic speech recognition ars tree master 1 技术路线 2 实现过程 层次聚类和K means聚类的样本是0 9语音每个数字各
  • 搭建AI智能语音外呼系统

    随着人工智能技术的发展 近半年来涌现了大量基于人工智能的呼叫中心业务服务商和集成商 仅电销机器人这一个方向就至少有近百家公司正在推广运营 包括百度 讯飞 智齿 硅基 百应 箭鱼 容联等 商务上的需求非常强烈 整个市场都飞快地热闹起来 一套可
  • 传统语音增强——基本的维纳滤波语音降噪算法

    一 维纳滤波的基本原理 基本维纳滤波就是用来解决从噪声中提取信号问题的一种过滤 或滤波 方法 它基于平稳随机过程模型 且假设退化模型为线性空间不变系统的 实际上这种线性滤波问题 可以看成是一种估计问题或一种线性估计问题 基本的维纳滤波是根据
  • windows下写入文本换行符\r\n修改为linux下换行符\n

    最近一段时间经常使用python向文本写入数据 但是windows下换行符默认为 r n 而linux下换行符为 n 写入的文本要在linux下调用 这就很坑人了 代码前行的路上怎么能被小小石头绊倒 于是乎搜索了一通 发现这个事情仅需要几行
  • 音频处理-2 WAV格式

    后续要将流量中的音频数据转为WAV格式文件 所以本节重点说下WAV格式 WAV文件是在PC机平台上很常见的 最经典的多媒体音频文件 最早于1991年8月出现在Windows 3 1操作系统上 文件扩展名为WAV 是WaveFom的简写 也称
  • 一文了解语音合成技术(TTS)

    TTS是Text To Speech的缩写 即 从文本到语音 它将计算机自己产生的 或外部输入的文字信息转变为可以听得懂的 流利的汉语口语 或者其他语言语音 输出的技术 隶属于语音合成 SpeechSynthesis 语音 在人类的发展过程
  • 人脸识别解决方案全套文件大合集,120份全新精选,有这个就够了

    人脸识别解决方案全套文件大合集 120份全新精选 有这个就够了 一 人脸识别4个特点 二 人脸识别的 4 个步骤 三 人脸识别的 5 个难点 四 人脸识别算法的发展轨迹 五 人脸识别的典型应用 六 下载人脸识别全套解决方案 一 人脸识别4个
  • 大话水声通信技术---(BFSK仿真)

    在之前的理论篇中 笔者梳理了水声通信相关的理论知识体系 本次笔者给出了一套基于BFSK的水声通信系统 该系统已经在实际的硬件中得到了验证 通信声呐仿真BPSK方式 几点假设 1 基于射线声学理论 2 几何衰减按球面波传播衰减规律衰减 不考虑
  • 利用百度AI 合成语音2

    文字合成语音 coding UTF 8 from aip import AipSpeech from playsound import playsound 你的 APPID AK SK APP ID 20232679 API KEY bZc
  • Montreal Forced Aligner (MFA)安装教程&失败原因集合

    写在前面 本文章只考虑2 x版本以后的安装时遇到的问题 推荐大家看官方的安装教程 里面设计不同系统 不同场景的安装方式 官网安装教程地址 https montreal forced aligner readthedocs io en lat
  • GB28181设备接入端如何播放语音广播数据?

    技术背景 语音广播功能是GB28181设备接入端非常重要的功能属性 语音广播让终端和平台之间 有了实时双向互动 可以满足执法记录仪 智能安全帽 智能监控 智慧零售 智慧教育 远程办公 明厨亮灶 智慧交通 智慧工地 雪亮工程 平安乡村 生产运
  • 个性化语音生成:五种基于Python的方法

    引言 随着人工智能技术的不断发展 语音生成已经成为一个热门的研究领域 个性化语音生成技术可以根据用户的需求和特点 生成具有高度相似度的语音 广泛应用于语音助手 虚拟人物 语音合成等领域 本文将介绍五种基于Python的个性化语音生成方法 包

随机推荐

  • C++在路径下新建一个指定名称的文件夹

    在保存数据是 我们希望将新生成的数据单独保存在一个文件夹中 其实我们可以通过程序自动生成一个指定名称的文件夹 存放数据 而不必提前手动新建文件夹并修改名称 代码实现的方法也很简单 但是需要注意的是该方法需要包含windows h头文件 代如
  • 树莓派——制作静态库、动态库

    库的特点 库是可执行代码的二进制形式 即将源代码转换成二进制的源代码 相当于对源代码进行了加密 别人可以看见库使用库 但是看不见库的源代码 2种类型库 静态库 libxxx a 动态库 libxxx so 静态库 在程序执行前就加入到目标程
  • Spring IoC是什么

    IoC是什么 Ioc Inversion of Control 即 控制反转 不是什么技术 而是一种设计思想 在Java开发中 Ioc意味着将你设计好的对象交给容器控制 而不是传统的在你的对象内部直接控制 如何理解好Ioc呢 理解好Ioc的
  • FDTD solutions——TFSF(全场散射场)光源及斜入射

    每天一遍 防止忘记 初始建立仿真文件 1 建立物理结构 几何结构 材料特性 2 定义仿真区域 边界条件 3 设置激励源 光源 4 设置监视器 至少使用一个时间监视器 分析组 只记录需要的数据 运行与仿真 1 运行仿真文件 分布式并行运算 并
  • 深度学习中的目标识别

    博主简介 博主是一名大二学生 主攻人工智能研究 感谢让我们在CSDN相遇 博主致力于在这里分享关于人工智能 c Python 爬虫等方面知识的分享 如果有需要的小伙伴可以关注博主 博主会继续更新的 如果有错误之处 大家可以指正 专栏简介 本
  • 车联网企业排行榜

    1 为紧跟车联网行业发展动态 聚焦优质市场主体 中国价值公司100排行榜之车联网企业排行榜从经营分析 发展能力以及社会责任三个维度对30家车联网重点企业进行综合评分 2 车载信息服务领域 市场主体多样 角色多元 以百度 腾讯 博泰 四维图新
  • K8s-yaml的使用及命令

    YAML配置文件管理对象 对象管理 创建deployment资源 kubectl create f nginx deployment yaml 查看deployment kubectl get deploy 查看ReplicaSet kub
  • 超详细OpenStack一键式部署

    1 准备镜像文件 Cen1 创建新的虚拟机 1 创建虚拟机 点击关闭 2 安装Centos7 密码自己设置 不用跟着一样 2 生成动态IP地址 root localhost dhclient 3 查看生成的IP地址 root localho
  • Windows安装子系统Linux

    Windows安装子系统 Linux ubuntu 安装条件 步骤 1 安装WSL命令 2 设置Linux用户名和密码 3 写个简单的 c程序看看 4 如何互传文件 安装条件 Windows 10版本2004及更高的版本才能安装 步骤 1
  • 多模态中的指令控制(InstructPix2Pix,SayCan)

    InstructPix2Pix Learning to Follow Image Editing Instructions 图像的语言指令生成 目的是遵循人工指令去编辑图像 即给定输入图像和一个如何编辑它的文本指令 模型尝试遵循这些指令来编
  • 数据治理:数据治理之道-数据文化-数据思维融入企业文化

    参考 一本书讲透数据治理 数据治理 等 大数据的根本价值在于从数据的不确定性中发现规律 获得确定性 想要在繁杂的大数据中快速找到价值数据 并依靠数据发现 分析 解决 跟踪问题 企业必须有数据思维与数据文化 数字转型 文化先行 数字化趋势下
  • Node.js学习笔记

    一 初识Node js 1 Node js是什么 1 Node js是一个基于Chrome V8 引擎的 JavaScript 运行环境 2 Node js官网 http nodejs cn 2 运行环境 注意 浏览器是JavaScript
  • 运放相位(频率)补偿电路设计

    集成运放的内部是一个多级放大器 其对数幅频特性如图 1所示中的曲线 实线 对数幅频特性曲线在零分贝以上的转折点称为极点 图中 称P1 P2点为极点 极点对应的频率称为转折频率 如fp1 fp2 第一个极点 即频率最低的极点称为主极点 在极点
  • Java实现远程调试

    https www cnblogs com wwywwy p 9626078 html 远程调试 主动连接调试 服务端配置监控端口 本地IDE连接远程监听端口进行调试 一般调试问题用这种方式 被动连接调试 本地IDE监听某端口 等待远程连接
  • 分段和分页内存管理

    两者描述 打个比方 比如说你去听课 带了一个纸质笔记本做笔记 笔记本有100张纸 课程有语文 数学 英语三门 对于这个笔记本的使用 为了便于以后复习方便 你可以有两种选择 第一种是 你从本子的第一张纸开始用 并且事先在本子上做划分 第2张到
  • 数据结构笔记:PR四叉树

    1 基本介绍 在PR四叉树中 每个节点代表一个矩形区域 并且每个节点要么没有子节点 要么有四个子节点 分别代表该矩形区域的四个象限 2 数据结构 PR四叉树的每个节点通常包含以下几个元素 区域 矩形 节点所代表的二维空间范围 点 存储在该区
  • 零售超市如何应对消费者需求?非常全面!

    随着科技的飞速发展和消费者期望的不断演变 零售行业正经历着一场深刻的革命 传统零售模式逐渐被新零售模式所取代 而其中一个备受关注的元素是自动售货机 自动售货机不仅在商场 车站和办公楼等高流量地点迅速扩张 还在重新定义我们如何购物 何时购物以
  • js数组转tree

    数组转 tree目前发现就三种方式 js版本实现了三种 初始化数据 let arr name 李四 id 2 pid 0 name 王五 id 3 pid 0 name 赵六 id 4 pid 3 name 吗六 id 9 pid 3 na
  • Latex编辑器Texstudio的快捷键汇总(更新)

    Latex编辑器Texstudio的注释快捷键 注释 Ctrl T 去除注释 Ctrl U
  • 语音识别之端点检测

    在之前呢我们已经把portaudio平台搭好了 可以采集声音信号并播放了 那么接下来呢我们就来做一些实质性的东西 自适应端点检测 那么什么是自适应端点检测呢 也就是采集声音信号的时候 开始说话到说话结束 我们把这一段声音信号采集下来进行处理