diff --git a/software/apps/audio_module/event_detector/Makefile b/software/apps/audio_module/event_detector/Makefile new file mode 100644 index 00000000..79be72e1 --- /dev/null +++ b/software/apps/audio_module/event_detector/Makefile @@ -0,0 +1,24 @@ +# makefile for user application + +# the current directory +APP_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +# files needed for this code +C_SRCS := $(wildcard *.c) +C_SRCS := $(wildcard **/log2fix.c) +#C_SRCS += ./log2fix/log2fix.c +#C_SRCS += ./kiss_fft/kiss_fft.c +#C_SRCS += ./kiss_fft/tools/kiss_fftr.c +#C_SRCS += ./gcwa/c/ridgeTracker.c +#C_SRCS += ./gcwa/c/dynArray.c + +INCLUDE_PATHS += . ./kiss_fft ./kiss_fft/tools ./log2fix ./gcwa/c + +CFLAGS += -DFIXED_POINT=16 -std=c99 +CFLAGS += -Wno-type-limits -Wno-sign-compare + +TOCK_BOARD = audio_module + +# include makefile settings that are shared between applications +include ../../AppMakefile.mk + diff --git a/software/apps/audio_module/event_detector/README.md b/software/apps/audio_module/event_detector/README.md new file mode 100644 index 00000000..59887354 --- /dev/null +++ b/software/apps/audio_module/event_detector/README.md @@ -0,0 +1,25 @@ +# Universal acoustic event detection app +The first step into any audio processing chain. + +Detect a large class of "acoustic events" (bird calls, gunshots, broken glasses, etc.) from noisy background. +Further classifications are reserved for downstream processing. + +## Quick start +1. Plug the Audio Module into the `Module 1` slot + +2. **Important** Make sure the programming knob is turned to `MOD1`. + +3. Get all the prerequisites (See below) + +4. Flash the app + + ```bash + cd signpost/software/apps/audio_module/event_detector + make flash + ``` + +## Prerequisites +* Fixed-point FFT: git clone https://github.com/longle2718/kiss_fft +* Fixed-point log: git clone https://github.com/dmoulding/log2fix +* Ridge tracker: git clone https://bitbucket.org/longle1/gcwa + * Fixed-point implementation in C is under gcwa/c/ diff --git a/software/apps/audio_module/event_detector/main.c b/software/apps/audio_module/event_detector/main.c new file mode 100644 index 00000000..8570acf2 --- /dev/null +++ b/software/apps/audio_module/event_detector/main.c @@ -0,0 +1,161 @@ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "app_watchdog.h" +#include "signpost_api.h" +#include "simple_post.h" +#include "_kiss_fft_guts.h" +#include "kiss_fftr.h" +#include "common.h" +#include "ridgeTracker.h" + +static int freqAnalyze(kiss_fft_scalar *frame, kiss_fft_scalar *spec); +static int printMat(char *filename, kiss_fft_scalar *in, size_t N); +static int printMat2(char *filename, size_t *in, size_t N); + +int main (void) { + int err = SUCCESS; + printf("[Audio Module] Event Detector\n"); + + // initialize ADC + err = adc_initialize(); + if (err < SUCCESS) { + printf("Initialize errored: %d\n", err); + } + + static kiss_fft_scalar frame[BUF_LEN]; + static kiss_fft_scalar spec[FRE_LEN]; + static kiss_fft_scalar snrOut[FRE_LEN]; + memset(frame, 0, BUF_LEN*sizeof(kiss_fft_scalar)); + size_t frameIdx = 0; + size_t globTI = 0; + ridgeTracker_init(); + while (true) { + // read data from ADC + for (size_t k = frameIdx; k < frameIdx+INC_LEN; k++){ + err = adc_read_single_sample(3); + if (err < SUCCESS) { + printf("ADC read error: %d\n", err); + } + uint16_t sample = err & 0xFFFF; + frame[k] = (kiss_fft_scalar)sample; + } + frameIdx = (frameIdx+INC_LEN) % BUF_LEN; + + // perform FFT + if (freqAnalyze(frame, spec)){ + printf("freqAnalyze() failed!\n"); + return 1; + } + + // ridgetracker update + ridgeTracker_update(spec, snrOut); + + // check for available event + if (ridgeTracker_isReady){ + printf("Event detected!\n"); + printf("ridgeTracker_out.used = %zu\n",ridgeTracker_out.used); + + if (printMat("SNR.mat",ridgeTracker_out.SNR,ridgeTracker_out.used)){ + printf("printMat() failed!\n"); + return 1; + } + if (printMat2("FI.mat",ridgeTracker_out.FI,ridgeTracker_out.used)){ + printf("printMat2() failed!\n"); + return 1; + } + size_t TIE = ridgeTracker_out.TI[ridgeTracker_out.used-1]; + for (size_t k=0; k