📄 spectrum.c
字号:
//****************************************************************************//// SPECTRUM.C - Software spectrum analyzer.//// Copyright (c) 2001 Cirrus Logic, Inc.////****************************************************************************#include "spectrum.h"//****************************************************************************//// The filters used to extract the spectral content for the various bands.////****************************************************************************#if NUMBANDS == 5static const short ppsFilter[3][22] ={ // // Sample rate = 32000 // { // // Low pass (0 - 110) // 175, 16034, // // Band pass (110 - 220) // -164, 415, -249, 32582, -16214, // // Band pass (220 - 622) // -542, 1698, -1154, 32041, -15771, // // Band pass (622 - 1760) // 18, 1666, -1683, 30176, -14682, // // High pass (1760 - 16000) // 12816, 24778, -10102 }, // // Sample rate = 44100 // { // // Low pass (0 - 110) // 127, 16129, // // Band pass (110 - 220) // -176, 415, -237, 32636, -16261, // // Band pass (220 - 622) // -627, 1700, -1072, 32262, -15938, // // Band pass (622 - 1760) // -219, 1685, -1463, 31047, -15139, // // High pass (1760 - 22050) // 13718, 26959, -11528 }, // // Sample rate = 48000 // { // // Low pass (0 - 110) // 117, 16150, // // Band pass (110 - 220) // -178, 415, -235, 32648, -16271, // // Band pass (220 - 622) // -645, 1701, -1054, 32307, -15974, // // Band pass (622 - 1760) // -271, 1688, -1415, 31219, -15238, // // High pass (1760 - 24000) // 13919, 27430, -11861 }};#endif//****************************************************************************//// Determines the absolute value of the given value.////****************************************************************************#define ABS(x) ((x) >= 0 ? (x) : 0 - (x))//****************************************************************************//// Clears the state of the spectrum analyzer.////****************************************************************************static voidSpectrumClear(tSpectrumAnalyzer *pSpectrum){ unsigned long ulBand, ulBucket; // // Loop through all the bands in the spectrum analyzer. // for(ulBand = 0; ulBand < NUMBANDS; ulBand++) { // // Loop through all the buckets in this band. // for(ulBucket = 0; ulBucket < NUMBUCKETS; ulBucket++) { // // Clear this bucket. // pSpectrum->ulBucket[ulBand][ulBucket] = 0; } } // // Clear the delay lines. // for(ulBand = 0; ulBand < (((NUMBANDS - 1) * 2) + 3); ulBand++) { pSpectrum->sMemory[ulBand] = 0; } // // Reset back to the first bucket. // pSpectrum->usCurrentBucket = 0; // // There are no samples in the current bucket. // pSpectrum->usSamplesInBucket = 0;}//****************************************************************************//// FilterMono applies the tone control filter to the given mono sample stream.////****************************************************************************static voidFilterMono(tSpectrumAnalyzer *pSpectrum, short *psInData, long lNumSamples){ const short *psCoeffPtr; short *psMemPtr, sSample, sValue, sBand; // // Loop through all the input samples. // while(lNumSamples--) { // // Get a pointer to the coefficients. // psCoeffPtr = pSpectrum->psFilter; // // Get a pointer to the delay line memory. // psMemPtr = pSpectrum->sMemory + 2; // // Get the next sample value. // sSample = *psInData++; // // The first band is a low pass filter. // sValue = ((sSample * psCoeffPtr[0]) + (*psMemPtr * psCoeffPtr[1])) >> 14; // // Save the output value for the next iteration of the filter. // *psMemPtr++ = sValue; // // Skip this filter's coefficients. // psCoeffPtr += 2; // // Add the absolute value of this sample (which is indicative of it's // spectral power) to the current bucket. // pSpectrum->ulBucket[0][pSpectrum->usCurrentBucket] += ABS(sValue); // // Loop through the band pass filters. // for(sBand = 1; sBand < (NUMBANDS - 1); sBand++) { // // Filter this sample. // sValue = ((sSample * psCoeffPtr[0]) + (pSpectrum->sMemory[0] * psCoeffPtr[1]) + (pSpectrum->sMemory[1] * psCoeffPtr[2]) + (psMemPtr[0] * psCoeffPtr[3]) + (psMemPtr[1] * psCoeffPtr[4])) >> 14; // // Update the output sample delay line. // psMemPtr[1] = psMemPtr[0]; psMemPtr[0] = sValue; // // Skip this filter's delay line. // psMemPtr += 2; // // Skip this filter's coefficients. // psCoeffPtr += 5; // // Add the absolute value of this sample (which is indicative of // it's spectral power) to the current bucket. // pSpectrum->ulBucket[sBand][pSpectrum->usCurrentBucket] += ABS(sValue); } // // The last band is a Chebyshev high pass filter. // sValue = (((sSample - pSpectrum->sMemory[0] - pSpectrum->sMemory[0] + pSpectrum->sMemory[1]) * psCoeffPtr[0]) + (psMemPtr[0] * psCoeffPtr[1]) + (psMemPtr[1] * psCoeffPtr[2])) >> 14; // // Update the output sample delay line. // psMemPtr[1] = psMemPtr[0]; psMemPtr[0] = sValue; // // Add the absolute value of this sample (which is indicative of it's // spectral power) to the current bucket. // pSpectrum->ulBucket[sBand][pSpectrum->usCurrentBucket] += ABS(sValue); // // Update the input sample delay line. // pSpectrum->sMemory[1] = pSpectrum->sMemory[0]; pSpectrum->sMemory[0] = sSample; // // Increment the number of samples in this bucket. // pSpectrum->usSamplesInBucket++; // // See if this bucket is now full. // if(pSpectrum->usSamplesInBucket == NUMSAMPLES) { // // The bucket is full, so advance to the next bucket. // pSpectrum->usCurrentBucket = ((pSpectrum->usCurrentBucket + 1) & (NUMBUCKETS - 1)); // // There are no samples in the new bucket. // pSpectrum->usSamplesInBucket = 0; // // Clear the previous contents of this bucket. // for(sBand = 0; sBand < NUMBANDS; sBand++) { pSpectrum->ulBucket[sBand][pSpectrum->usCurrentBucket] = 0; } } }}//****************************************************************************//// FilterStereo applies the tone control filter to the given pair of mono// sample streams.////****************************************************************************static voidFilterStereo(tSpectrumAnalyzer *pSpectrum, short *psInDataLeft, short *psInDataRight, long lNumSamples){ const short *psCoeffPtr; short *psMemPtr, sSample, sValue, sBand; // // Loop through all the input samples. // while(lNumSamples--) { // // Get a pointer to the coefficients. // psCoeffPtr = pSpectrum->psFilter; // // Get a pointer to the delay line memory. // psMemPtr = pSpectrum->sMemory + 2; // // Get the next sample value. // sSample = (*psInDataLeft++ + *psInDataRight++) >> 1; // // The first band is a low pass filter. // sValue = ((sSample * psCoeffPtr[0]) + (*psMemPtr * psCoeffPtr[1])) >> 14; // // Save the output value for the next iteration of the filter. // *psMemPtr++ = sValue; // // Skip this filter's coefficients. // psCoeffPtr += 2; // // Add the absolute value of this sample (which is indicative of it's // spectral power) to the current bucket. // pSpectrum->ulBucket[0][pSpectrum->usCurrentBucket] += ABS(sValue); // // Loop through the band pass filters. // for(sBand = 1; sBand < (NUMBANDS - 1); sBand++) { // // Filter this sample. // sValue = ((sSample * psCoeffPtr[0]) + (pSpectrum->sMemory[0] * psCoeffPtr[1]) + (pSpectrum->sMemory[1] * psCoeffPtr[2]) + (psMemPtr[0] * psCoeffPtr[3]) + (psMemPtr[1] * psCoeffPtr[4])) >> 14; // // Update the output sample delay line. // psMemPtr[1] = psMemPtr[0]; psMemPtr[0] = sValue; // // Skip this filter's delay line. // psMemPtr += 2; // // Skip this filter's coefficients. // psCoeffPtr += 5; // // Add the absolute value of this sample (which is indicative of // it's spectral power) to the current bucket. // pSpectrum->ulBucket[sBand][pSpectrum->usCurrentBucket] += ABS(sValue); } // // The last band is a Chebyshev high pass filter. // sValue = (((sSample - pSpectrum->sMemory[0] - pSpectrum->sMemory[0] + pSpectrum->sMemory[1]) * psCoeffPtr[0]) + (psMemPtr[0] * psCoeffPtr[1]) + (psMemPtr[1] * psCoeffPtr[2])) >> 14; // // Update the output sample delay line. // psMemPtr[1] = psMemPtr[0]; psMemPtr[0] = sValue; // // Add the absolute value of this sample (which is indicative of it's // spectral power) to the current bucket. // pSpectrum->ulBucket[sBand][pSpectrum->usCurrentBucket] += ABS(sValue); // // Update the input sample delay line. // pSpectrum->sMemory[1] = pSpectrum->sMemory[0]; pSpectrum->sMemory[0] = sSample; // // Increment the number of samples in this bucket. // pSpectrum->usSamplesInBucket++; // // See if this bucket is now full. // if(pSpectrum->usSamplesInBucket == NUMSAMPLES) { // // The bucket is full, so advance to the next bucket. // pSpectrum->usCurrentBucket = ((pSpectrum->usCurrentBucket + 1) & (NUMBUCKETS - 1)); // // There are no samples in the new bucket. // pSpectrum->usSamplesInBucket = 0; // // Clear the previous contents of this bucket. // for(sBand = 0; sBand < NUMBANDS; sBand++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -