怎么用soundtouch对某具体音频文件的数据流做处理

怎么用soundtouch对某具体音频文件的数据流做处理,第1张

SoundTouch音频处理库的使用异常简单,经过简单的编译之后,设置编译环境,以vc为例

,直接在include包含SoundTouch目录下的include路径,接着在lib添加SoundTouch目录下

的lib路径,然后在代码的头文件中添加头文件以及引用的库。如下:根据_DEBUG这个宏,

我们可以进行一些编译预处理,假如是以DEBUG编译就采用debug库,其他的话就采用

release库。他们的区别就是文件名后面是否多了一个“D”。

#include <SoundTouch.h>

#ifdef _DEBUG

#pragma comment(lib, "SoundTouchD.lib")

#else

#pragma comment(lib, "SoundTouch.lib")

#endif

当然你也可以直接在vc的项目工程中直接添加,某些人比较喜欢如此。

最重要的一点还要声明一个命名空间,至于原因,和SoundTouch这个库的声明定义有关,

以下在分析的时候会提到。

using namespace soundtouch

然后就可以直接在自己的代码中定义一个类变量SoundTouch m_SoundTouch

SoundTouch 类的声明包含在SoundTouch.h和SoundTouch.cpp之中,由FIFOProcessor类直

接派生,而FIFOProcessor类又直接从基类FIFOSamplePipe派生。同时声明SoundTouch这个

类包含在命名空间 soundtouch,这就是为什么我们使用这个库的时候需要声明命名空间的

主要原因。感觉有点多余。且仅仅定义了一些常量,诸如版本号,版本ID号等等,这两个

父类都包含在FIFOSamplePipe.h和FIFOSamplePipe.cpp文件中。

不管什么库,如果要使用的话,一般的流程都是先定义然后进行一些必要的初始化,

SoundTouch(以下简称ST)也不例外。ST的初始化也和他的编译一样异常的简单,具体可以

参考他的例子SoundStretch来实现,也可以参考源代码中有关SoundTouch这个类的声明,

现在只关心我们会用到的那部分,可以看到在private中定义了另外两个类指针

RateTransposer*,TDStretch*;

RateTransposer从FIFOProcessor派生,而FIFOProcessor又直接从基类FIFOSamplePipe派

生,TDStretch和RateTransposer类似。由此可见,单单从两个类的名字上看:拉长?传输

速率?不难想象出这个库对声音信号的处理可能就是“拉长”,然后“变速”。难道就是传说

中的不变调变速?事实正是如此。这还不是我们现在关心的话题。

……

private:

/// Rate transposer class instance

class RateTransposer *pRateTransposer

/// Time-stretch class instance

class TDStretch *pTDStretch

/// Virtual pitch parameter. Effective rate &tempo are calculated from

these parameters.

float virtualRate

/// Virtual pitch parameter. Effective rate &tempo are calculated from

these parameters.

float virtualTempo

/// Virtual pitch parameter. Effective rate &tempo are calculated from

these parameters.

float virtualPitch

/// Flag: Has sample rate been set?

BOOL bSrateSet

/// Calculates effective rate &tempo valuescfrom 'virtualRate',

'virtualTempo' and

/// 'virtualPitch' parameters.

void calcEffectiveRateAndTempo()

protected :

/// Number of channels

uint channels

/// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo'

and 'virtualPitch'

float rate

/// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo'

and 'virtualPitch'

float tempo

/// Sets new rate control value. Normal rate = 1.0, smaller values

/// represent slower rate, larger faster rates.

void setRate(float newRate)

/// Sets new tempo control value. Normal tempo = 1.0, smaller values

/// represent slower tempo, larger faster tempo.

void setTempo(float newTempo)

/// Sets new rate control value as a difference in percents compared

/// to the original rate (-50 .. +100 %)

void setRateChange(float newRate)

/// Sets new tempo control value as a difference in percents compared

/// to the original tempo (-50 .. +100 %)

void setTempoChange(float newTempo)

/// Sets new pitch control value. Original pitch = 1.0, smaller values

/// represent lower pitches, larger values higher pitch.

void setPitch(float newPitch)

/// Sets pitch change in octaves compared to the original pitch

/// (-1.00 .. +1.00)

void setPitchOctaves(float newPitch)

/// Sets pitch change in semi-tones compared to the original pitch

/// (-12 .. +12)

void setPitchSemiTones(int newPitch)

void setPitchSemiTones(float newPitch)

/// Sets the number of channels, 1 = mono, 2 = stereo

void setChannels(uint numChannels)

/// Sets sample rate.

void setSampleRate(uint srate)

/// Changes a setting controlling the processing system behaviour. See the

/// 'SETTING_...' defines for available setting ID's.

/// /return 'TRUE' if the setting was succesfully changed

BOOL setSetting(int settingId, ///<Setting ID number. see SETTING_...

defines.

int value///<New setting value.

)

……

参考ST提供的例子SoundStretch,初始化SoundTouch这个类:

m_SoundTouch.setSampleRate(sampleRate)//设置声音的采样频率

m_SoundTouch.setChannels(channels)//设置声音的声道

m_SoundTouch.setTempoChange(tempoDelta)//这个就是传说中的变速不变调

m_SoundTouch.setPitchSemiTones(pitchDelta)//设置声音的pitch

m_SoundTouch.setRateChange(rateDelta)//设置声音的速率

// quick是一个bool变量,USE_QUICKSEEK具体有什么用我暂时也不太清楚。

m_SoundTouch.setSetting(SETTING_USE_QUICKSEEK, quick)

// noAntiAlias是一个bool变量,USE_AA_FILTER具体有什么用我暂时也不太清楚。

m_SoundTouch.setSetting(SETTING_USE_AA_FILTER, !(noAntiAlias))

// speech也是一个bool变量,初步估计可能是没有音乐只有人声的时候,需要设置一下。

if (speech)

{

// use settings for speech processing

m_SoundTouch.setSetting(SETTING_SEQUENCE_MS, 40)

m_SoundTouch.setSetting(SETTING_SEEKWINDOW_MS, 15)

m_SoundTouch.setSetting(SETTING_OVERLAP_MS, 8)

fprintf(stderr, "Tune processing parameters for speech processing./n")

}

通过那么简单的几个函数调用,现在我们就可以感受一下ST的强大。通过SoundTouch类提

供的函数调用方法:

putSamples(sampleBuffer,nSamples)

第一个参数为一个指向PCM编码的一段音频数据的指针,第二个参数就是要处理多少个

sample也可以理解为多少帧。

需要注意的是,一般数据流都是字节流,也就是说,sample的大小和声道、位的声音参数

有关,假如sampleBuffer指针指向一个 长度为64bytes的一个PCM数据缓冲区,16位2声道

,那么实际上这里只存放了(16*2)/8=4bytes,64/4=1616个sample,这是我们需要注意的

地方。m_SoundTouch.putSamples(sampleBuffer, nSamples)数据是传进去了,可是从哪

里接收处理过的音频数据呢?这个时候我们就要用SoundTouch提供的receiveSamples函数

调用方法。

uint receiveSamples(SAMPLETYPE *outBuffer, ///<Buffer where to copy output

samples.

uint maxSamples///<How many samples to receive at max.

)他也是两个参数,第一个为接收数据的参数,第二个最大可以接收多少sample。

通过这段注释,大概明白receiveSamples这个函数不会在putSamples之后马上返回数据,

另外一方面有可能返回比maxSamples更多的数据,因此需要放在一个do…while(…)的循环里

面把他们都榨干。

// Read ready samples from SoundTouch processor &write them output file.

// NOTES:

// - 'receiveSamples' doesn't necessarily return any samples at all

// during some rounds!

// - On the other hand, during some round 'receiveSamples' may have more

// ready samples than would fit into 'sampleBuffer', and for this reason

// the 'receiveSamples' call is iterated for as many times as it

// outputs samples.

do

{

nSamples = m_SoundTouch.receiveSamples(sampleBuffer, buffSizeSamples)

//把sampleBuffer写入一个文件,或者填充进声卡的缓冲区,播放声音。

} while (nSamples != 0)

今天就先写到这里,比较劳累。

转载

加上头文件 #include <mmsystem.h>

音频文件名改用英文 ASCII 字符,不含空格,而且要确认 音频文件 路径正确,名字拼写无误。可以是 mp3, wma, wav 等格式歌曲

#include<iostream>

using namespace std

#include <stdio.h>

#include <windows.h>

#include <mmsystem.h>

#pragma comment(lib, "winmm.lib")

int main()

{

PlaySound (TEXT("E:\\kugoumusic\\ssjs.mp3"), NULL, SND_ASYNC | SND_NODEFAULT)

while (1)

{

cout <<"program is running... here\n"

Sleep(1000)

}

return 0

}

手机也不能播放吧,应该是程序有错,最好把程序贴出来。

可以参考这个程序

http://blog.csdn.net/peijiangping1989/article/details/7042610


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12027636.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存