From 156aef782eea46c2d86575673f7f49382d0bd208 Mon Sep 17 00:00:00 2001 From: Raphael Gault Date: Mon, 20 Apr 2020 10:57:57 +0100 Subject: [PATCH 1/6] fft: Add cmsis submodule for fft computation Signed-off-by: Raphael Gault Merged CMakeLists.txt target link libraries with master - includes relevant CMSIS libraries. --- .gitmodules | 3 +++ CMSIS_5 | 1 + CMakeLists.txt | 25 +++++++++++++++++++++++++ target.json | 4 ++-- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 .gitmodules create mode 160000 CMSIS_5 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b46f77c1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "CMSIS_5"] + path = CMSIS_5 + url = https://github.com/ARM-software/CMSIS_5.git diff --git a/CMSIS_5 b/CMSIS_5 new file mode 160000 index 00000000..2e98b247 --- /dev/null +++ b/CMSIS_5 @@ -0,0 +1 @@ +Subproject commit 2e98b24711e8d73d425484334f3d54c41168ffd9 diff --git a/CMakeLists.txt b/CMakeLists.txt index 709b2a05..1284f606 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,9 +50,29 @@ RECURSIVE_FIND_FILE(LIB_ARCHIVE_FILES "${CMAKE_CURRENT_LIST_DIR}/lib" "*.a") set(CMAKE_SYSTEM_PROCESSOR "armv7-m" PARENT_SCOPE) +set(ROOT "${CMAKE_CURRENT_LIST_DIR}/CMSIS_5/") +list(APPEND INCLUDE_DIRS "${ROOT}/CMSIS/Core/Include/") + + +# Define the path to CMSIS-DSP (ROOT is defined on command line when using cmake) +set(DSP ${ROOT}/CMSIS/DSP) + +include(${DSP}/Toolchain/GCC.cmake) + +# Add DSP folder to module path +list(APPEND CMAKE_MODULE_PATH ${DSP}) + +########### +# +# CMSIS DSP +# + # add them include_directories(${INCLUDE_DIRS}) +# Load CMSIS-DSP definitions. Libraries will be built in bin_dsp +add_subdirectory(${DSP}/Source bin_dsp) + # create our target add_library(codal-microbit-v2 ${SOURCE_FILES}) @@ -61,6 +81,11 @@ target_link_libraries( codal-nrf52 codal-core codal-microbit-nrf5sdk + CMSISDSPSupport + CMSISDSPTransform + CMSISDSPCommon + CMSISDSPComplexMath + CMSISDSPStatistics ${LIB_OBJECT_FILES} ${LIB_ARCHIVE_FILES} ) diff --git a/target.json b/target.json index 5161fe0f..fd1760db 100644 --- a/target.json +++ b/target.json @@ -50,11 +50,11 @@ "cmake_definitions":{ "MBED_LEGACY_TOOLCHAIN":"GCC_ARM;" }, - "cpu_opts":"-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp", + "cpu_opts":"-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard", "asm_flags":"-fno-exceptions -fno-unwind-tables --specs=nosys.specs -mcpu=cortex-m4 -mthumb", "c_flags":"-std=c99 --specs=nosys.specs -Warray-bounds", "cpp_flags":"-std=c++11 -fwrapv -fno-rtti -fno-threadsafe-statics -fno-exceptions -fno-unwind-tables -Wl,--gc-sections -Wl,--sort-common -Wl,--sort-section=alignment -Wno-array-bounds", - "linker_flags":"-Wl,--no-wchar-size-warning -Wl,--gc-sections -Wl,--wrap,atexit -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -Wl,--end-group", + "linker_flags":"-Wl,--no-wchar-size-warning -Wl,--gc-sections -Wl,--wrap,atexit -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -Wl,--end-group", "libraries":[ { "name":"codal-core", From 20b30d15e51ad78dbee206613e3e41c7eb0fdc73 Mon Sep 17 00:00:00 2001 From: Raphael Gault Date: Mon, 20 Apr 2020 11:07:42 +0100 Subject: [PATCH 2/6] fft: Define MicroBitAudioProcessor Signed-off-by: Raphael Gault --- inc/MicroBitAudioProcessor.h | 52 +++++++++++++++ source/MicroBitAudioProcessor.cpp | 105 ++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 inc/MicroBitAudioProcessor.h create mode 100644 source/MicroBitAudioProcessor.cpp diff --git a/inc/MicroBitAudioProcessor.h b/inc/MicroBitAudioProcessor.h new file mode 100644 index 00000000..4fc90c45 --- /dev/null +++ b/inc/MicroBitAudioProcessor.h @@ -0,0 +1,52 @@ +/* +The MIT License (MIT) + +Copyright (c) 2020 Arm Limited. + +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. +*/ + +#include "MicroBit.h" +#include "DataStream.h" +#define ARM_MATH_CM4 +#include "arm_math.h" + +#ifndef MICROBIT_AUDIO_PROCESSOR_H +#define MICROBIT_AUDIO_PROCESSOR_H + +#define AUDIO_SAMPLES_NUMBER 256 + +class MicroBitAudioProcessor : public DataSink +{ + DataSource &audiostream; + int zeroOffset; // unsigned value that is the best effort guess of the zero point of the data source + int divisor; // Used for LINEAR modes + arm_rfft_fast_instance_f32 fft_instance; + float *buf; + float *output; + uint16_t position; + + public: + MicroBitAudioProcessor(DataSource& source); + ~MicroBitAudioProcessor(); + virtual int pullRequest(); + int setDivisor(int d); +}; + +#endif diff --git a/source/MicroBitAudioProcessor.cpp b/source/MicroBitAudioProcessor.cpp new file mode 100644 index 00000000..75ea97ca --- /dev/null +++ b/source/MicroBitAudioProcessor.cpp @@ -0,0 +1,105 @@ +/* +The MIT License (MIT) + +Copyright (c) 2020 Arm Limited. + +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. +*/ + +#include "MicroBit.h" +#include "MicroBitAudioProcessor.h" + +MicroBitAudioProcessor::MicroBitAudioProcessor(DataSource& source) : audiostream(source) +{ + audiostream.connect(*this); + zeroOffset = 0; + divisor = 1; + //arm_rfft_fast_init_f32(&fft_instance, AUDIO_SAMPLES_NUMBER); + + /* Double Buffering: We allocate twice the number of samples*/ + buf = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER * 2); + output = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER); + + position = 0; + + if (buf == NULL || output == NULL) { + DMESG("DEVICE_NO_RESOURCES"); + target_panic(DEVICE_OOM); + } +} + +MicroBitAudioProcessor::~MicroBitAudioProcessor() +{ + free(buf); + free(output); +} + +int MicroBitAudioProcessor::pullRequest() +{ + int z = 0; + int minimum = 0; + int maximum = 0; + int s; + int8_t result; + + auto mic_samples = audiostream.pull().getBytes(); + + int16_t *data = (int16_t *) &mic_samples[0]; + int samples = AUDIO_SAMPLES_NUMBER / 2; + + for (int i=0; i < samples; i++) + { + z += *data; + + s = (int) *data; + s = s - zeroOffset; + s = s / divisor; + result = (int8_t)s; + + if (s < minimum) + minimum = s; + + if (s > maximum) + maximum = s; + + data++; + buf[position++] = (float)result; + + if (!(position % AUDIO_SAMPLES_NUMBER)) + { + /* We have AUDIO_SAMPLES_NUMBER samples, we can run the FFT on them */ + uint8_t offset = position <= AUDIO_SAMPLES_NUMBER ? 0 : AUDIO_SAMPLES_NUMBER; + if (offset != 0) + position = 0; + + //arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0); + DMESG("o[0]: %d", output[0]); + } + } + + z = z / samples; + zeroOffset = z; + return DEVICE_OK; +} + +int MicroBitAudioProcessor::setDivisor(int d) +{ + divisor = d; + return DEVICE_OK; +} From 2830ec170edd925c0294a7f67b8f5fa475f078df Mon Sep 17 00:00:00 2001 From: Raphael Gault Date: Thu, 23 Apr 2020 09:05:47 +0100 Subject: [PATCH 3/6] fft: Capture microphone's feed and detect fundamental frequency Signed-off-by: Raphael Gault --- inc/MicroBitAudioProcessor.h | 8 ++++- source/MicroBitAudioProcessor.cpp | 59 ++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/inc/MicroBitAudioProcessor.h b/inc/MicroBitAudioProcessor.h index 4fc90c45..94e43eaf 100644 --- a/inc/MicroBitAudioProcessor.h +++ b/inc/MicroBitAudioProcessor.h @@ -30,7 +30,8 @@ DEALINGS IN THE SOFTWARE. #ifndef MICROBIT_AUDIO_PROCESSOR_H #define MICROBIT_AUDIO_PROCESSOR_H -#define AUDIO_SAMPLES_NUMBER 256 +#define MIC_SAMPLE_RATE (11 * 1024) +#define AUDIO_SAMPLES_NUMBER 1024 class MicroBitAudioProcessor : public DataSink { @@ -40,13 +41,18 @@ class MicroBitAudioProcessor : public DataSink arm_rfft_fast_instance_f32 fft_instance; float *buf; float *output; + float *mag; uint16_t position; + bool recording; + float rec[AUDIO_SAMPLES_NUMBER * 2]; public: MicroBitAudioProcessor(DataSource& source); ~MicroBitAudioProcessor(); virtual int pullRequest(); int setDivisor(int d); + void startRecording(); + void stopRecording(MicroBit& uBit); }; #endif diff --git a/source/MicroBitAudioProcessor.cpp b/source/MicroBitAudioProcessor.cpp index 75ea97ca..34ca8f3d 100644 --- a/source/MicroBitAudioProcessor.cpp +++ b/source/MicroBitAudioProcessor.cpp @@ -30,15 +30,17 @@ MicroBitAudioProcessor::MicroBitAudioProcessor(DataSource& source) : audiostream audiostream.connect(*this); zeroOffset = 0; divisor = 1; - //arm_rfft_fast_init_f32(&fft_instance, AUDIO_SAMPLES_NUMBER); + arm_rfft_fast_init_f32(&fft_instance, AUDIO_SAMPLES_NUMBER); /* Double Buffering: We allocate twice the number of samples*/ buf = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER * 2); output = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER); + mag = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER / 2); position = 0; + recording = false; - if (buf == NULL || output == NULL) { + if (buf == NULL || output == NULL || mag == NULL) { DMESG("DEVICE_NO_RESOURCES"); target_panic(DEVICE_OOM); } @@ -48,6 +50,7 @@ MicroBitAudioProcessor::~MicroBitAudioProcessor() { free(buf); free(output); + free(mag); } int MicroBitAudioProcessor::pullRequest() @@ -56,21 +59,24 @@ int MicroBitAudioProcessor::pullRequest() int minimum = 0; int maximum = 0; int s; - int8_t result; + int result; - auto mic_samples = audiostream.pull().getBytes(); + auto mic_samples = audiostream.pull(); + + if (!recording) + return DEVICE_OK; int16_t *data = (int16_t *) &mic_samples[0]; - int samples = AUDIO_SAMPLES_NUMBER / 2; + int samples = mic_samples.length() / 2; for (int i=0; i < samples; i++) { z += *data; s = (int) *data; - s = s - zeroOffset; - s = s / divisor; - result = (int8_t)s; + //s = s - zeroOffset; + //s = s / divisor; + result = s; if (s < minimum) minimum = s; @@ -78,18 +84,34 @@ int MicroBitAudioProcessor::pullRequest() if (s > maximum) maximum = s; + //if (recording) + // rec[position] = (float)result; + data++; buf[position++] = (float)result; + if (!(position % AUDIO_SAMPLES_NUMBER)) { - /* We have AUDIO_SAMPLES_NUMBER samples, we can run the FFT on them */ - uint8_t offset = position <= AUDIO_SAMPLES_NUMBER ? 0 : AUDIO_SAMPLES_NUMBER; + float maxValue = 0; + uint32_t index = 0; + + /* We have AUDIO_SAMPLES_NUMBER samples, we can run the FFT on them */ + uint16_t offset = position <= AUDIO_SAMPLES_NUMBER ? 0 : AUDIO_SAMPLES_NUMBER; if (offset != 0) position = 0; - //arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0); - DMESG("o[0]: %d", output[0]); + DMESG("Run FFT, %d", offset); + arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0); + arm_cmplx_mag_f32(output, mag, AUDIO_SAMPLES_NUMBER / 2); + arm_max_f32(mag + 1, AUDIO_SAMPLES_NUMBER / 2 - 1, &maxValue, &index); + + uint32_t freq = ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER) * (index + 1); + DMESG("Freq: %d (max: %d.%d, Index: %d)", + freq, + (int)maxValue, + ((int)(maxValue * 100) % 100), + index); } } @@ -103,3 +125,16 @@ int MicroBitAudioProcessor::setDivisor(int d) divisor = d; return DEVICE_OK; } + + +void MicroBitAudioProcessor::startRecording() +{ + this->recording = true; + DMESG("START RECORDING"); +} + +void MicroBitAudioProcessor::stopRecording(MicroBit& uBit) +{ + this->recording = false; + DMESG("STOP RECORDING"); +} From 7bf3cce03c366b93790fdad2cd67c48a5518842a Mon Sep 17 00:00:00 2001 From: Joshua Hill Date: Mon, 25 Jan 2021 09:53:20 +0000 Subject: [PATCH 4/6] Updating fft branch in line with origin. Added ability to query MicroBitAudioProcessor and sample fft C++ Program --- inc/MicroBitAudioProcessor.h | 2 + samples/fft_example.cpp | 76 +++++++++++++++++++++++++++++++ source/MicroBitAudioProcessor.cpp | 37 +++++++-------- 3 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 samples/fft_example.cpp diff --git a/inc/MicroBitAudioProcessor.h b/inc/MicroBitAudioProcessor.h index 94e43eaf..074e13e4 100644 --- a/inc/MicroBitAudioProcessor.h +++ b/inc/MicroBitAudioProcessor.h @@ -45,11 +45,13 @@ class MicroBitAudioProcessor : public DataSink uint16_t position; bool recording; float rec[AUDIO_SAMPLES_NUMBER * 2]; + int lastFreq; public: MicroBitAudioProcessor(DataSource& source); ~MicroBitAudioProcessor(); virtual int pullRequest(); + int getFrequency(); int setDivisor(int d); void startRecording(); void stopRecording(MicroBit& uBit); diff --git a/samples/fft_example.cpp b/samples/fft_example.cpp new file mode 100644 index 00000000..10d6b72d --- /dev/null +++ b/samples/fft_example.cpp @@ -0,0 +1,76 @@ +#include "MicroBit.h" +#include "CodalDmesg.h" +#include "MicroBitAudioProcessor.h" +#include "StreamNormalizer.h" +#include "Tests.h" + +static NRF52ADCChannel *mic = NULL; +static StreamNormalizer *processor = NULL; +static MicroBitAudioProcessor *fft = NULL; + +MicroBit uBit; + +/** + * fft_test function - creates an example MicroBitAudioProcessor and then queries it for results. + * Currently configured to use 1024 samples with 8bit signed data. + */ +void fft_test(){ + uBit.display.print("L"); + if (mic == NULL){ + mic = uBit.adc.getChannel(uBit.io.microphone); + mic->setGain(7,0); + } + + if (processor == NULL) + processor = new StreamNormalizer(mic->output, 1.0f, true, DATASTREAM_FORMAT_8BIT_SIGNED, 10); + + if (fft == NULL) + fft = new MicroBitAudioProcessor(processor->output); + + uBit.io.runmic.setDigitalValue(1); + uBit.io.runmic.setHighDrive(true); + + + //Start fft running + fft->startRecording(); + + + while(1){ + //TODO - de-noise : if last X samples are same - display ect. + //The output values depend on the input type (DATASTREAM_FORMAT_8BIT_SIGNED) and the size + //of the FFT - which is changed using the 'AUDIO_SAMPLES_NUMBER' in MicroBitAudioProcessor.h + //default is 1024 + uBit.sleep(100); + int freq = fft->getFrequency(); + DMESG("%s %d", "frequency: ", freq); + if(freq > 0) + uBit.display.print("?"); + if(freq > 530) + uBit.display.print("C"); + if(freq > 600) + uBit.display.print("D"); + if(freq > 680) + uBit.display.print("E"); + if(freq > 710) + uBit.display.print("F"); + if(freq > 800) + uBit.display.print("G"); + if(freq > 900) + uBit.display.print("A"); + if(freq > 1010) + uBit.display.print("B"); + if(freq > 1050) + uBit.display.print("?"); + } +} + + + +int +main() +{ + + uBit.init(); + fft_test(); + +} \ No newline at end of file diff --git a/source/MicroBitAudioProcessor.cpp b/source/MicroBitAudioProcessor.cpp index 34ca8f3d..5c76ef4d 100644 --- a/source/MicroBitAudioProcessor.cpp +++ b/source/MicroBitAudioProcessor.cpp @@ -55,9 +55,7 @@ MicroBitAudioProcessor::~MicroBitAudioProcessor() int MicroBitAudioProcessor::pullRequest() { - int z = 0; - int minimum = 0; - int maximum = 0; + int s; int result; @@ -66,27 +64,17 @@ int MicroBitAudioProcessor::pullRequest() if (!recording) return DEVICE_OK; + //using 8 bits produces more accurate to input results (not 2x like using 16) but issue with + //F and G both producing 363hz -> investigate futher with crossing 8 bit + differnet sample numbers + //int8_t *data = (int8_t *) &mic_samples[0]; int16_t *data = (int16_t *) &mic_samples[0]; int samples = mic_samples.length() / 2; for (int i=0; i < samples; i++) { - z += *data; - - s = (int) *data; - //s = s - zeroOffset; - //s = s / divisor; - result = s; - - if (s < minimum) - minimum = s; - - if (s > maximum) - maximum = s; - - //if (recording) - // rec[position] = (float)result; - + + result = (int) *data; + data++; buf[position++] = (float)result; @@ -102,9 +90,14 @@ int MicroBitAudioProcessor::pullRequest() position = 0; DMESG("Run FFT, %d", offset); + //auto a = system_timer_current_time(); arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0); arm_cmplx_mag_f32(output, mag, AUDIO_SAMPLES_NUMBER / 2); arm_max_f32(mag + 1, AUDIO_SAMPLES_NUMBER / 2 - 1, &maxValue, &index); + //auto b = system_timer_current_time(); + + //DMESG("Before FFT: %d", (int)a); + //DMESG("After FFT: %d (%d)", (int)b, (int)(b - a)); uint32_t freq = ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER) * (index + 1); DMESG("Freq: %d (max: %d.%d, Index: %d)", @@ -115,11 +108,13 @@ int MicroBitAudioProcessor::pullRequest() } } - z = z / samples; - zeroOffset = z; return DEVICE_OK; } +int MicroBitAudioProcessor::getFrequency(){ + return lastFreq; +} + int MicroBitAudioProcessor::setDivisor(int d) { divisor = d; From 22920ba570c5abd75fd86d86d41f623519ef06d1 Mon Sep 17 00:00:00 2001 From: Carlos Pereira Atencio Date: Wed, 29 Mar 2023 17:36:38 +0100 Subject: [PATCH 5/6] Minor updates to get the FFT sample running again. Although it currently calculates frequencies that are twice the signal frequency, but that might be a simple fix once somebody can look into the audio configuration. --- .github/workflows/build.yml | 2 +- .github/workflows/size-diff.yml | 1 + CMakeLists.txt | 2 +- samples/fft_example.cpp | 22 ++++++++++------------ source/MicroBitAudioProcessor.cpp | 6 ++---- target-locked.json | 4 ++-- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2203cb1d..e3f828dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: matrix: os: [ubuntu-20.04, macos-11, windows-2019] gcc: ['7-2017-q4', 'latest'] - cmake: ['3.6.0', ''] # Empty string installs the latest CMake release + cmake: ['3.13.0', ''] # Empty string installs the latest CMake release fail-fast: false runs-on: ${{ matrix.os }} name: ${{ matrix.os }}, gcc ${{ matrix.gcc }}, cmake ${{ matrix.cmake || 'latest'}} diff --git a/.github/workflows/size-diff.yml b/.github/workflows/size-diff.yml index 13efa379..3c81cb6b 100644 --- a/.github/workflows/size-diff.yml +++ b/.github/workflows/size-diff.yml @@ -116,6 +116,7 @@ jobs: run: | cd libraries/codal-microbit-v2 git checkout ${GIT_BASE_SHA} + git restore . - name: Build 'base' project using build.py run: python build.py --clean diff --git a/CMakeLists.txt b/CMakeLists.txt index 1284f606..80f3a581 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ RECURSIVE_FIND_FILE(LIB_ARCHIVE_FILES "${CMAKE_CURRENT_LIST_DIR}/lib" "*.a") set(CMAKE_SYSTEM_PROCESSOR "armv7-m" PARENT_SCOPE) -set(ROOT "${CMAKE_CURRENT_LIST_DIR}/CMSIS_5/") +set(ROOT "${CMAKE_CURRENT_LIST_DIR}/CMSIS_5") list(APPEND INCLUDE_DIRS "${ROOT}/CMSIS/Core/Include/") diff --git a/samples/fft_example.cpp b/samples/fft_example.cpp index 10d6b72d..1dd742c7 100644 --- a/samples/fft_example.cpp +++ b/samples/fft_example.cpp @@ -2,7 +2,6 @@ #include "CodalDmesg.h" #include "MicroBitAudioProcessor.h" #include "StreamNormalizer.h" -#include "Tests.h" static NRF52ADCChannel *mic = NULL; static StreamNormalizer *processor = NULL; @@ -14,8 +13,9 @@ MicroBit uBit; * fft_test function - creates an example MicroBitAudioProcessor and then queries it for results. * Currently configured to use 1024 samples with 8bit signed data. */ -void fft_test(){ +void fft_test() { uBit.display.print("L"); +/* if (mic == NULL){ mic = uBit.adc.getChannel(uBit.io.microphone); mic->setGain(7,0); @@ -29,13 +29,17 @@ void fft_test(){ uBit.io.runmic.setDigitalValue(1); uBit.io.runmic.setHighDrive(true); +*/ + // Code above commented out was from the original example, which can + // probably be replaced with this single line, but we need to double check + // the configuration because the fft calculation results are twice the frequency + fft = new MicroBitAudioProcessor(*uBit.audio.splitter->createChannel()); //Start fft running fft->startRecording(); - - while(1){ + while (1){ //TODO - de-noise : if last X samples are same - display ect. //The output values depend on the input type (DATASTREAM_FORMAT_8BIT_SIGNED) and the size //of the FFT - which is changed using the 'AUDIO_SAMPLES_NUMBER' in MicroBitAudioProcessor.h @@ -64,13 +68,7 @@ void fft_test(){ } } - - -int -main() -{ - +int main() { uBit.init(); fft_test(); - -} \ No newline at end of file +} diff --git a/source/MicroBitAudioProcessor.cpp b/source/MicroBitAudioProcessor.cpp index 5c76ef4d..f42acc1c 100644 --- a/source/MicroBitAudioProcessor.cpp +++ b/source/MicroBitAudioProcessor.cpp @@ -55,8 +55,6 @@ MicroBitAudioProcessor::~MicroBitAudioProcessor() int MicroBitAudioProcessor::pullRequest() { - - int s; int result; auto mic_samples = audiostream.pull(); @@ -99,9 +97,9 @@ int MicroBitAudioProcessor::pullRequest() //DMESG("Before FFT: %d", (int)a); //DMESG("After FFT: %d (%d)", (int)b, (int)(b - a)); - uint32_t freq = ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER) * (index + 1); + lastFreq = ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER) * (index + 1); DMESG("Freq: %d (max: %d.%d, Index: %d)", - freq, + lastFreq, (int)maxValue, ((int)(maxValue * 100) % 100), index); diff --git a/target-locked.json b/target-locked.json index 81c4585e..80c7f3ad 100644 --- a/target-locked.json +++ b/target-locked.json @@ -44,7 +44,7 @@ "USE_ACCEL_LSB": 0 }, "cpp_flags": "-std=c++11 -fwrapv -fno-rtti -fno-threadsafe-statics -fno-exceptions -fno-unwind-tables -Wl,--gc-sections -Wl,--sort-common -Wl,--sort-section=alignment -Wno-array-bounds", - "cpu_opts": "-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp", + "cpu_opts": "-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard", "definitions": "-DAPP_TIMER_V2 -DAPP_TIMER_V2_RTC1_ENABLED -DNRF_DFU_TRANSPORT_BLE=1 -DNRF52833_XXAA -DNRF52833 -DTARGET_MCU_NRF52833 -DNRF5 -DNRF52833 -D__CORTEX_M4 -DS113 -DTOOLCHAIN_GCC -D__START=target_start", "device": "MICROBIT", "generate_bin": true, @@ -69,7 +69,7 @@ "url": "https://github.com/microbit-foundation/codal-microbit-nrf5sdk" } ], - "linker_flags": "-Wl,--no-wchar-size-warning -Wl,--gc-sections -Wl,--wrap,atexit -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -Wl,--end-group", + "linker_flags": "-Wl,--no-wchar-size-warning -Wl,--gc-sections -Wl,--wrap,atexit -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -Wl,--end-group", "post_process": "", "processor": "NRF52833", "snapshot_version": "v0.2.50", From b6dca85c2e6332c2beacc9ca706443a19c8f03ee Mon Sep 17 00:00:00 2001 From: Carlos Pereira Atencio Date: Thu, 6 Apr 2023 17:00:02 +0100 Subject: [PATCH 6/6] CI: build the FFT example for the size diff workflow. --- .github/workflows/size-diff.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/size-diff.yml b/.github/workflows/size-diff.yml index 3c81cb6b..66f0f8fc 100644 --- a/.github/workflows/size-diff.yml +++ b/.github/workflows/size-diff.yml @@ -67,11 +67,13 @@ jobs: .replace('lancaster-university/codal-microbit-v2', '${GITHUB_REPOSITORY}') \ .replace('master', '${GITHUB_SHA}') \ .replace(',\n \"dev\": true', '')) - f = pathlib.Path('source/main.cpp') - f.write_text(f.read_text().replace('out_of_box_experience()', 'ble_test()')) EOF echo "coda.json after:" cat codal.json + - name: Move fft example + run: | + mv libraries/codal-microbit-v2/samples/fft_example.cpp source/main.cpp + cat source/main.cpp - name: Build using build.py run: python build.py - name: Save ELF file in a different directory @@ -117,6 +119,9 @@ jobs: cd libraries/codal-microbit-v2 git checkout ${GIT_BASE_SHA} git restore . + - name: Build the default OOB for the parent/base commit comparison + shell: bash + run: git checkout source/main.cpp - name: Build 'base' project using build.py run: python build.py --clean