Skip to content

Commit

Permalink
Add phase_vocoder, timeStretch and pitchShift algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
liufeigit committed Jan 17, 2024
1 parent 86d298d commit 4ad4df4
Show file tree
Hide file tree
Showing 8 changed files with 509 additions and 0 deletions.
129 changes: 129 additions & 0 deletions src/dsp/phase_vocoder.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//

#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

#include "../vector/flux_vector.h"
#include "../vector/flux_vectorOp.h"
#include "../vector/flux_complex.h"

#include "phase_vocoder.h"

/***
mDataArr1 stft time*fftLength
rate 0.5~2
slideLength fftLength/4
****/
void phase_vocoder(float *mRealArr1,float *mImageArr1,int nLength,int mLength,int slideLength,float rate,
float *mRealArr2,float *mImageArr2){
float *timeArr=NULL;
float *phiArr=NULL;
float *phaseArr=NULL;

float *arr1=NULL;
float *arr2=NULL;

float *arr3=NULL;
float *arr4=NULL;

int tLen=0;
int fLen=0;

fLen=mLength/2+1;
tLen=ceilf(nLength/rate);
__varange(0,nLength,rate,&timeArr);

phiArr=__vlinspace(0, M_PI*slideLength, fLen, 0);

phaseArr=__vnew(fLen, NULL);
__vcangle(mRealArr1,mImageArr1,fLen,phaseArr);

arr1=__vnew(fLen, NULL);
arr2=__vnew(fLen, NULL);

arr3=__vnew(fLen, NULL);
arr4=__vnew(fLen, NULL);
for(int i=0;i<tLen;i++){
int k=0;
float alpha=0;

float *rArr1=NULL;
float *iArr1=NULL;

float *rArr2=NULL;
float *iArr2=NULL;

k=floorf(timeArr[i]);
alpha=timeArr[i]-floorf(timeArr[i]);

if(k<nLength){
rArr1=mRealArr1+k*mLength;
iArr1=mImageArr1+k*mLength;
}
else{
memset(arr1,0,sizeof(float )*fLen);
memset(arr2,0,sizeof(float )*fLen);
rArr1=arr1;
iArr1=arr2;
}

if(k+1<nLength){
rArr2=mRealArr1+(k+1)*mLength;
iArr2=mImageArr1+(k+1)*mLength;
}
else{
memset(arr3,0,sizeof(float )*fLen);
memset(arr4,0,sizeof(float )*fLen);
rArr2=arr3;
iArr2=arr4;
}

__vcabs(rArr1, iArr1, fLen, arr1);
__vcabs(rArr2, iArr2, fLen, arr2);
__vmul_value(arr1, (1-alpha), fLen, NULL);
__vmul_value(arr2, alpha, fLen, NULL);

// cal data
for(int j=0;j<fLen;j++){
mRealArr2[i*mLength+j]=(arr1[j]+arr2[j])*cosf(phaseArr[j]);
mImageArr2[i*mLength+j]=(arr1[j]+arr2[j])*sinf(phaseArr[j]);
}

for(int j=fLen,l=mLength/2-1;j<mLength;j++,l--){
mRealArr2[i*mLength+j]=mRealArr2[i*mLength+l];
mImageArr2[i*mLength+j]=-mImageArr2[i*mLength+l];
}

// update phase
__vcangle(rArr2,iArr2,fLen,arr1);
__vcangle(rArr1,iArr1,fLen,arr2);
for(int j=0;j<fLen;j++){
float value=0;

value=arr1[j]-arr2[j]-phiArr[j];
value=value-2*M_PI*roundf(value/(2*M_PI));

phaseArr[j]+=(phiArr[j]+value);
}
}

free(timeArr);
free(phiArr);
free(phaseArr);

free(arr1);
free(arr2);
free(arr3);
free(arr4);
}









26 changes: 26 additions & 0 deletions src/dsp/phase_vocoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@


#ifndef PHASE_VOCODER_H
#define PHASE_VOCODER_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>

/***
mDataArr1 stft time*fftLength
rate 0.5~2
slideLength fftLength/4
****/
void phase_vocoder(float *mRealArr1,float *mImageArr1,int timeLength,int fftLength,int slideLength,float rate,
float *mRealArr2,float *mImageArr2);


#ifdef __cplusplus
}
#endif

#endif
99 changes: 99 additions & 0 deletions src/mir/pitchShift_algorithm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//

#include <string.h>
#include <math.h>

#include "../vector/flux_vector.h"
#include "../vector/flux_vectorOp.h"

#include "../util/flux_util.h"
#include "../dsp/resample_algorithm.h"

#include "timeStretch_algorithm.h"
#include "pitchShift_algorithm.h"

struct OpaquePitchShift{
TimeStretchObj timeStretchObj;
ResampleObj resampleObj;



};

/***
radix2Exp 12
WindowType hann
slideLength (1<<radix2Exp)/4
****/
int pitchShiftObj_new(PitchShiftObj *pitchShiftObj,int *radix2Exp,int *slideLength,WindowType *windowType){
int status=0;

TimeStretchObj timeStretchObj=NULL;
ResampleObj resampleObj=NULL;

PitchShiftObj ps=NULL;

int scale=1;
ResampleQualityType qualType=ResampleQuality_Fast;

ps=*pitchShiftObj=(PitchShiftObj )calloc(1,sizeof(struct OpaquePitchShift ));

resampleObj_new(&resampleObj,&qualType,&scale,NULL);
timeStretchObj_new(&timeStretchObj,radix2Exp,slideLength,windowType);

ps->timeStretchObj=timeStretchObj;
ps->resampleObj=resampleObj;

return status;
}

// nSemitone -12~12
void pitchShiftObj_pitchShift(PitchShiftObj pitchShiftObj,int samplate,int nSemitone,float *dataArr1,int dataLength1,float *dataArr2){
float rate=0;
int samplate2=0;

float *_dataArr=NULL;
int capacity=0;
int dataLength2=0;

if(nSemitone>12||nSemitone<-12){
return ;
}

rate=powf(2, -nSemitone*1.0/12);
samplate2=roundf(samplate/rate);

capacity=timeStretchObj_calDataCapacity(pitchShiftObj->timeStretchObj,rate,dataLength1);
_dataArr=__vnew(capacity, NULL);

// 1. timeStretch
dataLength2=timeStretchObj_timeStretch(pitchShiftObj->timeStretchObj,rate,dataArr1,dataLength1,_dataArr);

// 2. resample
// resampleObj_setSamplate(pitchShiftObj->resampleObj,samplate2,samplate);
resampleObj_setSamplateRatio(pitchShiftObj->resampleObj,rate);
resampleObj_resample(pitchShiftObj->resampleObj,_dataArr,dataLength2,dataArr2);


free(_dataArr);
}

void pitchShiftObj__free(PitchShiftObj pitchShiftObj){

if(pitchShiftObj){
timeStretchObj_free(pitchShiftObj->timeStretchObj);
resampleObj_free(pitchShiftObj->resampleObj);

free(pitchShiftObj);
}
}










33 changes: 33 additions & 0 deletions src/mir/pitchShift_algorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@


#ifndef PITCHSHIFT_ALGORITHM_H
#define PITCHSHIFT_ALGORITHM_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>

#include "../flux_base.h"

typedef struct OpaquePitchShift *PitchShiftObj;

/***
radix2Exp 12
WindowType hann
slideLength (1<<radix2Exp)/4
****/
int pitchShiftObj_new(PitchShiftObj *pitchShiftObj,int *radix2Exp,int *slideLength,WindowType *windowType);

// nSemitone -12~12
void pitchShiftObj_pitchShift(PitchShiftObj pitchShiftObj,int samplate,int nSemitone,float *dataArr1,int dataLength1,float *dataArr2);

void pitchShiftObj__free(PitchShiftObj pitchShiftObj);

#ifdef __cplusplus
}
#endif

#endif
Loading

0 comments on commit 4ad4df4

Please sign in to comment.