From 37c97e345d12f95dde44e1d1a4c2f2aadd4615bc Mon Sep 17 00:00:00 2001 From: sanine Date: Thu, 25 Aug 2022 14:54:53 -0500 Subject: add initial structure --- portaudio/qa/loopback/src/audio_analyzer.h | 187 +++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 portaudio/qa/loopback/src/audio_analyzer.h (limited to 'portaudio/qa/loopback/src/audio_analyzer.h') diff --git a/portaudio/qa/loopback/src/audio_analyzer.h b/portaudio/qa/loopback/src/audio_analyzer.h new file mode 100644 index 0000000..8d9f1ee --- /dev/null +++ b/portaudio/qa/loopback/src/audio_analyzer.h @@ -0,0 +1,187 @@ + +/* + * PortAudio Portable Real-Time Audio Library + * Latest Version at: http://www.portaudio.com + * + * Copyright (c) 1999-2010 Phil Burk and Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +#ifndef _AUDIO_ANALYZER_H +#define _AUDIO_ANALYZER_H + +#include "biquad_filter.h" + +#define MATH_PI (3.141592653589793238462643) +#define MATH_TWO_PI (2.0 * MATH_PI) + +typedef struct PaQaSineGenerator_s +{ + double phase; + double phaseIncrement; + double frequency; + double amplitude; +} PaQaSineGenerator; + +/** Container for a monophonic audio sample in memory. */ +typedef struct PaQaRecording_s +{ + /** Maximum number of frames that can fit in the allocated buffer. */ + int maxFrames; + float *buffer; + /** Actual number of valid frames in the buffer. */ + int numFrames; + int sampleRate; +} PaQaRecording; + +typedef struct PaQaTestTone_s +{ + int samplesPerFrame; + int startDelay; + double sampleRate; + double frequency; + double amplitude; +} PaQaTestTone; + +typedef struct PaQaAnalysisResult_s +{ + int valid; + /** Latency in samples from output to input. */ + double latency; + double amplitudeRatio; + double popAmplitude; + double popPosition; + double numDroppedFrames; + double droppedFramesPosition; + double numAddedFrames; + double addedFramesPosition; +} PaQaAnalysisResult; + + +/*================================================================*/ +/*================= General DSP Tools ============================*/ +/*================================================================*/ +/** + * Calculate Nth frequency of a series for use in testing multiple channels. + * Series should avoid harmonic overlap between channels. + */ +double PaQa_GetNthFrequency( double baseFrequency, int index ); + +void PaQa_EraseBuffer( float *buffer, int numFrames, int samplesPerFrame ); + +void PaQa_MixSine( PaQaSineGenerator *generator, float *buffer, int numSamples, int stride ); + +void PaQa_WriteSine( float *buffer, int numSamples, int stride, + double frequency, double amplitude ); + +/** + * Generate a signal with a sharp edge in the middle that can be recognized despite some phase shift. + */ +void PaQa_GenerateCrack( float *buffer, int numSamples, int stride ); + +double PaQa_ComputePhaseDifference( double phase1, double phase2 ); + +/** + * Measure the area under the curve by summing absolute value of each value. + */ +double PaQa_MeasureArea( float *buffer, int numFrames, int stride ); + +/** + * Measure slope of the positive zero crossings. + */ +double PaQa_MeasureCrossingSlope( float *buffer, int numFrames ); + + +/** + * Prepare an oscillator that can generate a sine tone for testing. + */ +void PaQa_SetupSineGenerator( PaQaSineGenerator *generator, double frequency, double amplitude, double frameRate ); + +/*================================================================*/ +/*================= Recordings ===================================*/ +/*================================================================*/ +/** + * Allocate memory for containing a mono audio signal. Set up recording for writing. + */ + int PaQa_InitializeRecording( PaQaRecording *recording, int maxSamples, int sampleRate ); + +/** +* Free memory allocated by PaQa_InitializeRecording. + */ + void PaQa_TerminateRecording( PaQaRecording *recording ); + +/** + * Apply a biquad filter to the audio from the input recording and write it to the output recording. + */ +void PaQa_FilterRecording( PaQaRecording *input, PaQaRecording *output, BiquadFilter *filter ); + + +int PaQa_SaveRecordingToWaveFile( PaQaRecording *recording, const char *filename ); + +/** + * @param stride is the spacing of samples to skip in the input buffer. To use every samples pass 1. To use every other sample pass 2. + */ +int PaQa_WriteRecording( PaQaRecording *recording, float *buffer, int numSamples, int stride ); + +/** Write zeros into a recording. */ +int PaQa_WriteSilence( PaQaRecording *recording, int numSamples ); + +int PaQa_RecordFreeze( PaQaRecording *recording, int numSamples ); + +double PaQa_CorrelateSine( PaQaRecording *recording, double frequency, double frameRate, + int startFrame, int numSamples, double *phasePtr ); + +double PaQa_FindFirstMatch( PaQaRecording *recording, float *buffer, int numSamples, double tolerance ); + +/** + * Estimate the original amplitude of a clipped sine wave by measuring + * its average slope at the zero crossings. + */ +double PaQa_MeasureSineAmplitudeBySlope( PaQaRecording *recording, + double frequency, double frameRate, + int startFrame, int numFrames ); + +double PaQa_MeasureRootMeanSquare( float *buffer, int numFrames ); + +/** + * Compare the amplitudes of these two signals. + * Return ratio of recorded signal over buffer signal. + */ +double PaQa_CompareAmplitudes( PaQaRecording *recording, int startAt, float *buffer, int numSamples ); + +/** + * Analyse a recording of a sine wave. + * Measure latency and look for dropped frames, etc. + */ +int PaQa_AnalyseRecording( PaQaRecording *recording, PaQaTestTone *testTone, PaQaAnalysisResult *analysisResult ); + +#endif /* _AUDIO_ANALYZER_H */ -- cgit v1.2.1