📄 pan_picola.c
字号:
*OutputFlag = 1; return; }else { while(OutputPoint<EndPoint) { OutputSignal[WritePoint++] = SignalBuffer[OutputPoint++]; } /* <- output array is not filled */ /* requires next frame input */ if(OutputPoint>=FrameLength) { for(i=0;i<BufferLength-FrameLength;i++) { SignalBuffer[i] = SignalBuffer[i+FrameLength]; } EndPoint -= FrameLength; TargetPoint -= FrameLength; OutputPoint -= FrameLength; } *DecodeFlag = 1; *OutputFlag = 0; return; } }/* Slow play */ }else if(SpeedControlFactor<1. && SpeedControlFactor>=.5) { if(TargetPoint<=EndPoint) { if((FrameLength-WritePoint)<=(TargetPoint-OutputPoint)) { while(WritePoint<FrameLength) { OutputSignal[WritePoint++] = SignalBuffer[OutputPoint++]; } /* <- output array is filled */ /* but output point did not reach target point */ if(OutputPoint>=FrameLength+MaxPitch) { for(i=0;i<BufferLength-FrameLength;i++) { SignalBuffer[i] = SignalBuffer[i+FrameLength]; } EndPoint -= FrameLength; TargetPoint -= FrameLength; OutputPoint -= FrameLength; } WritePoint = 0; *OutputFlag = 1; *DecodeFlag = 0; return; }else { while(OutputPoint<TargetPoint) { OutputSignal[WritePoint++] = SignalBuffer[OutputPoint++]; } /* <- output point reached target point */ /* but output array is not filled */ if(OutputPoint>=FrameLength+MaxPitch) { for(i=0;i<BufferLength-FrameLength;i++) { SignalBuffer[i] = SignalBuffer[i+FrameLength]; } EndPoint -= FrameLength; TargetPoint -= FrameLength; OutputPoint -= FrameLength; } StartPoint = TargetPoint; /* PICOLA processing */ if(EndPoint-StartPoint<MaxPitch) { *DecodeFlag = 1; *OutputFlag = 0; return; }else { if(((StartPoint+MaxPitch) > BufferLength) || StartPoint<MaxPitch) { printf("\n PICOLA (speed control): buffer overflow\n"); printf(" process starting point = %d\n", StartPoint); printf(" waveform interval = %d\n", Pitch); exit(2); } pit_sel_backward(SignalBuffer+StartPoint); if(0!=Pitch) { StartPoint -= Pitch; for(i=0;i<Pitch;i++){ coef = (i+1)/(float)(Pitch+1); SignalBuffer[StartPoint+i] = coef*SignalBuffer[StartPoint+i] + (1.-coef)*SignalBuffer[StartPoint+Pitch+i]; } OutputPoint = StartPoint; TargetPoint = StartPoint + (int)(SpeedControlFactor/(1.-SpeedControlFactor)*Pitch+Pitch); }else { OutputPoint = StartPoint; TargetPoint = StartPoint+FrameLength; printf("\n PICOLA processing is skipped"); } } } }else { if((FrameLength-WritePoint)<=(EndPoint-OutputPoint)) { while(WritePoint<FrameLength) { OutputSignal[WritePoint++] = SignalBuffer[OutputPoint++]; } /* <- output array is filled */ /* remains samples to be outputed */ if(OutputPoint>=FrameLength+MaxPitch) { for(i=0;i<BufferLength-FrameLength;i++) { SignalBuffer[i] = SignalBuffer[i+FrameLength]; } EndPoint -= FrameLength; TargetPoint -= FrameLength; OutputPoint -= FrameLength; } WritePoint = 0; *DecodeFlag = 0; *OutputFlag = 1; return; }else { while(OutputPoint<EndPoint) { OutputSignal[WritePoint++] = SignalBuffer[OutputPoint++]; } /* <- output array is not filled */ /* requires next frame input */ if(OutputPoint>=FrameLength+MaxPitch) { for(i=0;i<BufferLength-FrameLength;i++) { SignalBuffer[i] = SignalBuffer[i+FrameLength]; } EndPoint -= FrameLength; TargetPoint -= FrameLength; OutputPoint -= FrameLength; } *DecodeFlag = 1; *OutputFlag = 0; return; } } }else { printf("\n Out of control range !!\n"); exit(3); }/*printf(" start=%d\n", StartPoint);printf(" end=%d\n", EndPoint);printf(" target=%d\n", TargetPoint);printf(" out=%d\n", OutputPoint);printf(" write=%d\n", WritePoint);printf(" pitch=%d\n", Pitch);printf(" in=%d\n", NumInputSample);printf("\n");*/ } }void pit_sel_backward( float *Signal){ int i, j; float MinError; float Error; float CrossCorrelation; float PastSignalEnergy; float CurrentSignalEnergy; Pitch = 0; MinError = 1.0e20; PastSignalEnergy = 0.; CurrentSignalEnergy = 0.; for(i=1;i<MinPitch;i++) { PastSignalEnergy += (*(Signal-i))*(*(Signal-i)); CurrentSignalEnergy += (*(Signal+i-1))*(*(Signal+i-1)); } for(j=MinPitch;j<=MaxPitch;j++) { PastSignalEnergy += (*(Signal-j))*(*(Signal-j)); CurrentSignalEnergy += (*(Signal+j-1))*(*(Signal+j-1)); CrossCorrelation = 0.; for(i=0;i<j;i++) CrossCorrelation += (*(Signal-j+i))*(*(Signal+i)); Error = (PastSignalEnergy + CurrentSignalEnergy - 2*CrossCorrelation) /(float)j; if((MinError>Error) && (CrossCorrelation>0.)) { MinError = Error; Pitch = j; } } if(0==Pitch) { if((PastSignalEnergy<1.) || (CurrentSignalEnergy<1.)) { Pitch = MinPitch; } }}void pit_sel_forward( float *Signal){ int i, j; float MinError; float Error; float CrossCorrelation; float FirstHalfEnergy; float SecondHalfEnergy; FirstHalfEnergy = 0.; SecondHalfEnergy = 0.; for(i=0;i<MinPitch-1;i++) { FirstHalfEnergy += (*(Signal+i))*(*(Signal+i)); SecondHalfEnergy += (*(Signal+i+MinPitch-1))*(*(Signal+i+MinPitch-1)); } Pitch = 0; MinError = 1.0e20; for(j=MinPitch;j<=MaxPitch;j++) { FirstHalfEnergy += (*(Signal+j-1))*(*(Signal+j-1)); SecondHalfEnergy += ((*(Signal+j*2-1))-(*(Signal+j-1))) *((*(Signal+j*2-1))+(*(Signal+j-1))); SecondHalfEnergy += (*(Signal+j*2-2))*(*(Signal+j*2-2)); CrossCorrelation = 0.; for(i=0;i<j;i++) CrossCorrelation += (*(Signal+j+i))*(*(Signal+i)); Error = (FirstHalfEnergy + SecondHalfEnergy - 2*CrossCorrelation) /(float)j; if((MinError>Error) && (CrossCorrelation>0.)) { MinError = Error; Pitch =j; } } if(0==Pitch) { if((FirstHalfEnergy<1.) || (SecondHalfEnergy<1.)) { Pitch = MinPitch; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -