예제 #1
0
Pitch PitchDetector::process2queue_average(float *input, unsigned int numberOfSamples)
{
    static double sumFre = 0.0;
    static double sumAmp = 0.0;
    Pitch pitch = this->process(input, numberOfSamples);
    if (this->pitchQueue.size() > this->queueSize) {
        Pitch front_pitch = this->pitchQueue.front();
        sumFre -= front_pitch.frequency;
        sumAmp -= front_pitch.amplitude;
        this->pitchQueue.pop();
        this->pitchQueue.push(pitch);
        sumFre += pitch.frequency;
        sumAmp += pitch.amplitude;
        
        // 计算平均
        this->bestPitch.frequency = sumFre/this->queueSize;
        this->bestPitch.amplitude = sumAmp/this->queueSize;
        this->bestPitch.key = 12 * log2(this->bestPitch.frequency / 127.09) + 28.5;
        this->bestPitch.octave = (this->bestPitch.key - 3.0) / 12 + 1;
        calStep(&this->bestPitch);
        this->bestPitch.stepString = calStep(this->bestPitch.frequency);
    } else {
        if (pitch.frequency > 0.0) {
            this->pitchQueue.push(pitch);
            sumFre += pitch.frequency;
            sumAmp += pitch.amplitude;
        }
    }
    if (this->bestPitch.amplitude == 0.0) {
        this->bestPitch = pitch;
    }
    return this->bestPitch;
}
예제 #2
0
Pitch PitchDetector::process(float *input, unsigned int numberOfSamples)
{
    assert(this->numberOfSamples==numberOfSamples);
    int n = numberOfSamples;
    float *originalReal = this->FFTBuffer;
    
    // 1.1.时域上加窗
    vDSP_vmul(input, 1, this->windowFunc, 1, originalReal, 1, n);
    // 分前后加窗没什么不一样啊
//    vDSP_vmul(input, 1, this->windowFunc, 1, originalReal+(n/2), 1, n/2);
//    vDSP_vmul(input+(n/2), 1, this->windowFunc+(n/2), 1, originalReal, 1, n/2);
    
    // 2.拆成复数形似{1+2i, 3+4i, ..., 1023+1024i} 原始数组可以认为是(COMPLEX*)交错存储 现在拆成COMPLEX_SPLIT非交错(分轨式)存储
    vDSP_ctoz((COMPLEX*)originalReal, 2, &this->A, 1, n/2); // 读取originalReal以2的步长塞进A里面
    
//    // 3.fft变换的预设
    float originalRealInLog2 = log2f(n);
//    FFTSetup setupReal = vDSP_create_fftsetup(originalRealInLog2, FFT_RADIX2);
    
    // 4.傅里叶变换
    vDSP_fft_zrip(this->setupReal, &this->A, 1, originalRealInLog2, FFT_FORWARD);
    
    // 5.转换成能量值
    vDSP_zvabs(&this->A, 1, this->magnitudes, 1, n/2);
    Float32 one = 1;
    vDSP_vdbcon(this->magnitudes, 1, &one, this->magnitudes, 1, n/2, 0);
    
    // 6.获取基频f0
    float maxValue;
    vDSP_Length index;
    vDSP_maxvi(this->magnitudes, 1, &maxValue, &index, n/2);
    // 6.1.微调参数
    double alpha    = this->magnitudes[index - 1];
    double beta     = this->magnitudes[index];
    double gamma    = this->magnitudes[index + 1];
    double p = 0.5 * (alpha - gamma) / (alpha - 2 * beta + gamma);
    
    // 7.转换为频率 indexHZ = index * (SampleRate / (n/2))
    float indexHZ = (index+p) * ((this->sampleRate*1.0) / n);
    
    // 8.乐理信息生成
    Pitch pitch;
    pitch.frequency = indexHZ;
    pitch.amplitude = beta;
    pitch.key = 12 * log2(indexHZ / 127.09) + 28.5;
    pitch.octave = (pitch.key - 3.0) / 12 + 1;
    calStep(&pitch);
    pitch.stepString = calStep(indexHZ);
    
    return pitch;
}
예제 #3
0
파일: main.c 프로젝트: Moguf/Cumol
int main(void){
    float *xyz,*vel;
    //ベルレ法を使うため、初期配置と初速度を定義
    xyz=(float *)malloc(sizeof(float)*MOL_XYZ);
    vel=(float *)malloc(sizeof(float)*MOL_XYZ);
    init(xyz,vel);

    //vmd用に出力する
    show(xyz);
    
    //時間発展させる
    calStep(xyz,vel);
    
    free(xyz);
    free(vel);
    return 0;
}