diff --git a/.gitmodules b/.gitmodules index 8d873d1..4b88d16 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/pico-microphone"] path = lib/pico-microphone url = https://github.com/sandeepmistry/pico-microphone.git +[submodule "lib/pico-sdk"] + path = lib/pico-sdk + url = https://github.com/raspberrypi/pico-sdk diff --git a/CMakeLists.txt b/CMakeLists.txt index 799e397..8ed0e63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,9 +51,9 @@ target_sources(pico_micro_speech ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/tensorflow/lite/experimental/microfrontend/lib/window.c ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/tensorflow/lite/experimental/microfrontend/lib/window_util.c ${CMAKE_CURRENT_LIST_DIR}/src/audio_provider.cc - ${CMAKE_CURRENT_LIST_DIR}/src/command_responder.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/command_responder.cc ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/feature_provider.cpp - ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/main.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/main.cpp ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/main_functions.cpp ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/micro_features/micro_features_generator.cpp ${PICO_TFLMICRO_MICRO_SPEECH_PATH}/micro_features/micro_model_settings.cpp @@ -108,3 +108,4 @@ pico_enable_stdio_usb(pico_micro_speech 1) pico_enable_stdio_uart(pico_micro_speech 0) add_subdirectory("lib/pico-tflmicro" EXCLUDE_FROM_ALL) +add_subdirectory("lib/pico-microphone" EXCLUDE_FROM_ALL) diff --git a/lib/pico-sdk b/lib/pico-sdk new file mode 160000 index 0000000..afc10f3 --- /dev/null +++ b/lib/pico-sdk @@ -0,0 +1 @@ +Subproject commit afc10f3599c27147a6f34781b7102d86f58aa5f6 diff --git a/src/audio_provider.cc b/src/audio_provider.cc index 45b3163..9631f74 100644 --- a/src/audio_provider.cc +++ b/src/audio_provider.cc @@ -12,12 +12,13 @@ limitations under the License. #include "audio_provider.h" #include "micro_features/micro_model_settings.h" +#include + +extern "C" { #include "pico/analog_microphone.h" +} #include "pico/stdlib.h" -#include "hardware/adc.h" -#include "hardware/dma.h" -#include "hardware/irq.h" #define ADC_PIN 26 #define CAPTURE_CHANNEL 0 @@ -35,7 +36,6 @@ int16_t g_audio_output_buffer[kMaxAudioSampleSize]; // Mark as volatile so we can check in a while loop to see if // any samples have arrived yet. volatile int32_t g_latest_audio_timestamp = 0; -volatile int samples_read = 0; const struct analog_microphone_config config = { // GPIO to use for input, must be ADC compatible (GPIO 26 - 28) @@ -50,18 +50,10 @@ const struct analog_microphone_config config = { // number of samples to buffer .sample_buffer_size = ADC_BUFFER_SIZE, }; - -int16_t g_audio_sample_buffer[ADC_BUFFER_SIZE]; - } // namespace void CaptureSamples() { - // callback from library when all the samples in the library - // internal sample buffer are ready for reading - samples_read = analog_microphone_read(g_audio_sample_buffer, ADC_BUFFER_SIZE); - // This is how many bytes of new data we have each time this is called - int number_of_samples = samples_read; - int samples_read = 0; + // This is how many samples are read in const int number_of_samples = ADC_BUFFER_SIZE; // Calculate what timestamp the last audio sample represents const int32_t time_in_ms = @@ -74,12 +66,7 @@ void CaptureSamples() { const int capture_index = start_sample_offset % kAudioCaptureBufferSize; // Read the data to the correct place in our buffer // PDM.read(g_audio_capture_buffer + capture_index, DEFAULT_PDM_BUFFER_SIZE); - int16_t* out = g_audio_capture_buffer + capture_index; - uint16_t* in = g_audio_sample_buffer; - - for (int i = 0; i < number_of_samples; i++) { - *out++ = *in++; - } + analog_microphone_read(g_audio_capture_buffer + capture_index, ADC_BUFFER_SIZE); // This is how we let the outside world know that new audio data has arrived. g_latest_audio_timestamp = time_in_ms; } @@ -87,8 +74,9 @@ void CaptureSamples() { TfLiteStatus InitAudioRecording(tflite::ErrorReporter* error_reporter) { // initialize the analog microphone if (analog_microphone_init(&config) < 0) { - printf("analog microphone initialization failed!\n"); - while (1) { tight_loop_contents(); } + TF_LITE_REPORT_ERROR(error_reporter, + "analog microphone initialization failed!"); + while (1) { tight_loop_contents(); } } // set callback that is called when all the samples in the library @@ -97,8 +85,8 @@ TfLiteStatus InitAudioRecording(tflite::ErrorReporter* error_reporter) { // start capturing data from the analog microphone if (analog_microphone_start() < 0) { - printf("PDM microphone start failed!\n"); - while (1) { tight_loop_contents(); } + TF_LITE_REPORT_ERROR(error_reporter, "Analog microphone start failed"); + while (1) { tight_loop_contents(); } } // Block until we have our first audio sample diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..0fad500 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,39 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include + +#include "pico/stdlib.h" +#include "tusb.h" + +#include "main_functions.h" + +// This is the default main used on systems that have the standard C entry +// point. Other devices (for example FreeRTOS or ESP32) that have different +// requirements for entry code (like an app_main function) should specialize +// this main.cc file in a target-specific subfolder. +int main(int argc, char* argv[]) { + stdio_init_all(); + while (!tud_cdc_connected()) { + tight_loop_contents(); + } + + printf("micro-speech mic\n"); + + setup(); + while (true) { + loop(); + } +}