瀏覽代碼

Add AudioAnalyzeRMS (thanks sgorpi)

dds
PaulStoffregen 9 年之前
父節點
當前提交
fe4831c78b
共有 6 個文件被更改,包括 234 次插入1 次删除
  1. +1
    -0
      Audio.h
  2. +52
    -0
      analyze_rms.cpp
  3. +66
    -0
      analyze_rms.h
  4. +82
    -0
      examples/Analysis/PeakAndRMSMeterStereo/PeakAndRMSMeterStereo.ino
  5. +32
    -1
      gui/index.html
  6. +1
    -0
      keywords.txt

+ 1
- 0
Audio.h 查看文件

#include "analyze_tonedetect.h" #include "analyze_tonedetect.h"
#include "analyze_notefreq.h" #include "analyze_notefreq.h"
#include "analyze_peak.h" #include "analyze_peak.h"
#include "analyze_rms.h"
#include "control_sgtl5000.h" #include "control_sgtl5000.h"
#include "control_wm8731.h" #include "control_wm8731.h"
#include "control_ak4558.h" #include "control_ak4558.h"

+ 52
- 0
analyze_rms.cpp 查看文件

/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* 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, development funding 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.
*/


#include "analyze_rms.h"
#include <arm_math.h>

void AudioAnalyzeRMS::update(void)
{
audio_block_t *block;
int16_t rmsResult;

block = receiveReadOnly();
if (!block) {
return;
}

// not reinventing the wheel:
// use DSP packed 32i instructions as found in arm_math.h, with 64b accumulator
arm_rms_q15(block->data, AUDIO_BLOCK_SAMPLES, &rmsResult); // seems to use ~2% CPU
lastRMS = rmsResult; // prevent threading issues
// for optimization, one could re-implement arm_rms_q15 to do the sqrt on read().
// This way, the rms in dB could also be implemented faster:
// Instead of 20*log10(sqrt(MSerror)), one could do write 10*log10(MSerror)

new_output = true;
release(block);
}


+ 66
- 0
analyze_rms.h 查看文件

/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* 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, development funding 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.
*/

#ifndef analyze_rms_h_
#define analyze_rms_h_

#include "AudioStream.h"

class AudioAnalyzeRMS : public AudioStream
{
private:
audio_block_t *inputQueueArray[1];
volatile bool new_output;
int16_t lastRMS;

public:
AudioAnalyzeRMS(void) : AudioStream(1, inputQueueArray) {
lastRMS = 0;
}

bool available(void) {
__disable_irq();
bool flag = new_output; // we don't reset new_output here, because if you don't read it,
//it'll still be available on the next call of available()
// (different from AnalyzePeak behavior, which resets it in available())
__enable_irq();
return flag;
}

float read(void) {
__disable_irq();
int rms = lastRMS;
new_output = false; // we can always set the new_output to false, even if it was false already
__enable_irq();
return rms / 32767.0;
}

virtual void update(void);
};

#endif


+ 82
- 0
examples/Analysis/PeakAndRMSMeterStereo/PeakAndRMSMeterStereo.ino 查看文件

/* Adaptation of Stereo peak meter example, including RMS.
assumes Audio adapter but just uses terminal so no more parts required.

This example code is in the public domain
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

const int myInput = AUDIO_INPUT_LINEIN;
// const int myInput = AUDIO_INPUT_MIC;

AudioInputI2S audioInput; // audio shield: mic or line-in
AudioAnalyzePeak peak_L;
AudioAnalyzePeak peak_R;
AudioAnalyzeRMS rms_L;
AudioAnalyzeRMS rms_R;
AudioOutputI2S audioOutput; // audio shield: headphones & line-out

AudioConnection c1(audioInput, 0, peak_L, 0);
AudioConnection c2(audioInput, 1, peak_R, 0);
AudioConnection c3(audioInput, 0, rms_L, 0);
AudioConnection c4(audioInput, 1, rms_R, 0);
AudioConnection c5(audioInput, 0, audioOutput, 0);
AudioConnection c6(audioInput, 1, audioOutput, 1);

AudioControlSGTL5000 audioShield;


void setup() {
AudioMemory(6);
audioShield.enable();
audioShield.inputSelect(myInput);
audioShield.volume(0.5);
Serial.begin(9600);
}

// for best effect make your terminal/monitor a minimum of 62 chars wide and as high as you can.

elapsedMillis fps;
uint8_t cnt=0;

void loop() {
if(fps > 24) {
if (peak_L.available() && peak_R.available() && rms_L.available() && rms_R.available()) {
fps=0;
uint8_t leftPeak = peak_L.read() * 30.0;
uint8_t rightPeak = peak_R.read() * 30.0;
uint8_t leftRMS = rms_L.read() * 30.0;
uint8_t rightRMS = rms_R.read() * 30.0;

for (cnt=0; cnt < 30-leftPeak; cnt++) {
Serial.print(" ");
}
while (cnt++ < 29 && cnt < 30-leftRMS) {
Serial.print("<");
}
while (cnt++ < 30) {
Serial.print("=");
}
Serial.print("||");
for(cnt=0; cnt < rightRMS; cnt++) {
Serial.print("=");
}
for(; cnt < rightPeak; cnt++) {
Serial.print(">");
}
while(cnt++ < 30) {
Serial.print(" ");
}
Serial.print(AudioProcessorUsage());
Serial.print("/");
Serial.print(AudioProcessorUsageMax());
Serial.println();
}
}
}

+ 32
- 1
gui/index.html 查看文件

{"type":"AudioFilterFIR","data":{"defaults":{"name":{"value":"new"}},"shortName":"fir","inputs":1,"outputs":1,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}}, {"type":"AudioFilterFIR","data":{"defaults":{"name":{"value":"new"}},"shortName":"fir","inputs":1,"outputs":1,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioFilterStateVariable","data":{"defaults":{"name":{"value":"new"}},"shortName":"filter","inputs":2,"outputs":3,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}}, {"type":"AudioFilterStateVariable","data":{"defaults":{"name":{"value":"new"}},"shortName":"filter","inputs":2,"outputs":3,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioAnalyzePeak","data":{"defaults":{"name":{"value":"new"}},"shortName":"peak","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, {"type":"AudioAnalyzePeak","data":{"defaults":{"name":{"value":"new"}},"shortName":"peak","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioAnalyzeRMS","data":{"defaults":{"name":{"value":"new"}},"shortName":"rms","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioAnalyzeFFT256","data":{"defaults":{"name":{"value":"new"}},"shortName":"fft256","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, {"type":"AudioAnalyzeFFT256","data":{"defaults":{"name":{"value":"new"}},"shortName":"fft256","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioAnalyzeFFT1024","data":{"defaults":{"name":{"value":"new"}},"shortName":"fft1024","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, {"type":"AudioAnalyzeFFT1024","data":{"defaults":{"name":{"value":"new"}},"shortName":"fft1024","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioAnalyzeToneDetect","data":{"defaults":{"name":{"value":"new"}},"shortName":"tone","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, {"type":"AudioAnalyzeToneDetect","data":{"defaults":{"name":{"value":"new"}},"shortName":"tone","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
</div> </div>
</script> </script>


<script type="text/x-red" data-help-name="AudioAnalyzeRMS">
<h3>Summary</h3>
<p>Track the signal RMS amplitude. Useful for
audio level response projects, and general troubleshooting.</p>
<h3>Audio Connections</h3>
<table class=doc align=center cellpadding=3>
<tr class=top><th>Port</th><th>Purpose</th></tr>
<tr class=odd><td align=center>In 0</td><td>Signal to analyze</td></tr>
</table>
<h3>Functions</h3>
<p class=func><span class=keyword>available</span>();</p>
<p class=desc>Returns true if new RMS data is available.
</p>
<p class=func><span class=keyword>read</span>();</p>
<p class=desc>Read the new RMS value.
Return is from 0.0 to 1.0.
</p>
<h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; Analysis &gt; PeakAndRMSMeterStereo</p>
</p>
<h3>Notes</h3>
<p></p>
</script>
<script type="text/x-red" data-template-name="AudioAnalyzeRMS">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>

<script type="text/x-red" data-help-name="AudioAnalyzeFFT256"> <script type="text/x-red" data-help-name="AudioAnalyzeFFT256">
<h3>Summary</h3> <h3>Summary</h3>
<p>Compute a 256 point Fast Fourier Transform (FFT) frequency analysis, <p>Compute a 256 point Fast Fourier Transform (FFT) frequency analysis,


<script type="text/x-red" data-help-name="AudioControlAK4558"> <script type="text/x-red" data-help-name="AudioControlAK4558">
<h3>Summary</h3> <h3>Summary</h3>
<p>Control the AK4558 chip on the <a href="https://hackaday.io/project/8567-hifi-audio-codec-module" target="_blank">HiFi Audio CODEC Module</a>
<p>Control the AK4558 chip on the <a href="https://hackaday.io/project/8567-hifi-audio-codec-module" target="_blank">HiFi Audio CODEC Module</a>
in slave mode, where the Teensy controls all I2S timing.</p> in slave mode, where the Teensy controls all I2S timing.</p>
<h3>Audio Connections</h3> <h3>Audio Connections</h3>
<p>This object has no audio inputs or outputs. Separate I2S objects <p>This object has no audio inputs or outputs. Separate I2S objects

+ 1
- 0
keywords.txt 查看文件

AudioAnalyzeFFT256 KEYWORD2 AudioAnalyzeFFT256 KEYWORD2
AudioAnalyzeFFT1024 KEYWORD2 AudioAnalyzeFFT1024 KEYWORD2
AudioAnalyzePeak KEYWORD2 AudioAnalyzePeak KEYWORD2
AudioAnalyzeRMS KEYWORD2
AudioAnalyzePrint KEYWORD2 AudioAnalyzePrint KEYWORD2
AudioAnalyzeToneDetect KEYWORD2 AudioAnalyzeToneDetect KEYWORD2
AudioAnalyzeNoteFrequency KEYWORD2 AudioAnalyzeNoteFrequency KEYWORD2

Loading…
取消
儲存