我正在试着在一个样本上做音调变换。我使用的是线性插值方法。
如果基准量是一个整数值,则基准值被整齐地移位。如果音调偏移的量是合理的,那么声音就会严重失真。这个实现似乎起作用了。
这是我的代码,我试着注释好。
public void generateOutTrack()
{
Note currNote;
float[] output=new float[pattern.getPlayTimeInSmps()];//returns total play time of pattern in #samples.
float[] currSample=sample.getData();//the pcm data of the sample to be used
int currPeriod=0;//length of next note in number of samples
int outputPtr=0;//points to next sample in output buffer array
float pitch;//amount to pitch sample by
float linInt=0;//linear interpolater
float phasePtr=0;//floating point index in sample
int ptr=0;//integer index into sample
JavAud.checkRange(currSample);
while((currNote=pattern.nextNote())!=null)//each iteration plays one note
{
currPeriod=currNote.getPeriodInSmps();//length of current note in samples
pitch=currNote.getPitch();//pitch of current note
for(int i=0;i<currPeriod;i++)//run for length of note
{
ptr=(int)phasePtr;//floor of floating point index
linInt=phasePtr-ptr;
//if we are not at end of sample copy data to output
if(ptr<currSample.length*(1/pitch)-1)
{
//linear interpolation pitch shifting
output[outputPtr]=(currSample[ptr+1]*linInt)+(currSample[ptr]*(1-linInt));
//alternate pitch shifting by simple sample dropping(has less distortion)
//output[outputPtr]=currSample[ptr];
}
else//else silent
{
output[outputPtr]=0;
}
outputPtr++;
phasePtr=phasePtr+pitch;
}
phasePtr=0;
}
JavAud.checkRange(output);
WavFileWriter writer = new WavFileWriter();
writer.writeWave(new WavFile(1, JavAud.GLB_SMP_RATE, output), "outputTone.wav");
}发布于 2014-02-18 12:01:11
看起来你是想通过重采样来改变音调。要实现比线性插值更好的质量重采样,一种常见的方法是使用加窗正弦低通滤波器作为插值内核。窗口Sinc重采样的一种(慢速)方法的伪代码如下:http://www.nicholson.com/rhn/dsp.html#3
https://stackoverflow.com/questions/21843564
复制相似问题