I made the following changes to the main.c file in the hello_analog_microphone sample
/*
* Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
*
* This examples captures data from an analog microphone using a sample
* rate of 8 kHz and prints the sample values over the USB serial
* connection.
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/analog_microphone.h"
#include "tusb.h"
#define AUDIO_SAMPLE_RATE 8000
#define RECORD_LENGTH_S 10
// configuration
const struct analog_microphone_config config = {
// GPIO to use for input, must be ADC compatible (GPIO 26 - 28)
.gpio = 26,
// bias voltage of microphone in volts
.bias_voltage = 0.0,
// sample rate in Hz
// .sample_rate = 8000,
.sample_rate = AUDIO_SAMPLE_RATE,
// number of samples to buffer
.sample_buffer_size = 256,
};
// variables
int16_t sample_buffer[256];
volatile int samples_read = 0;
int16_t full_record[AUDIO_SAMPLE_RATE * RECORD_LENGTH_S];
int full_record_INDEX = 0;
void on_analog_samples_ready()
{
// callback from library when all the samples in the library
// internal sample buffer are ready for reading
samples_read = analog_microphone_read(sample_buffer, 256);
}
int main( void )
{
bool break_while = false;
// initialize stdio and wait for USB CDC connect
stdio_init_all();
while (!tud_cdc_connected()) {
tight_loop_contents();
}
printf("hello analog microphone\n");
// initialize the analog microphone
if (analog_microphone_init(&config) < 0) {
printf("analog microphone initialization failed!\n");
while (1) { tight_loop_contents(); }
}
// set callback that is called when all the samples in the library
// internal sample buffer are ready for reading
analog_microphone_set_samples_ready_handler(on_analog_samples_ready);
// start capturing data from the analog microphone
if (analog_microphone_start() < 0) {
printf("PDM microphone start failed!\n");
while (1) { tight_loop_contents(); }
}
printf("record audio\n");
while (1) {
// store and clear the samples read from the callback
int sample_count = samples_read;
samples_read = 0;
// loop through any new collected samples
for (int i = 0; i < sample_count; i++) {
// printf("%d\n", sample_buffer[i]);
full_record[full_record_INDEX++] = sample_buffer[i];
if(full_record_INDEX >= AUDIO_SAMPLE_RATE*RECORD_LENGTH_S){
break_while = true;
break; // break inner for loop in case this does not happen at end of loop
// at this point AUDIO_SAMPLE_RATE*RECORD_LENGTH_S number of sample should be available in memory
}
}
if(break_while == true) break; // break the while() loop if this happens
}
printf("Recording complete, stop mic\n");
analog_microphone_stop();
analog_microphone_deinit();
printf("Sending recorded data to serial\n");
// send the AUDIO_SAMPLE_RATE*RECORD_LENGTH_S number of audio samples to USB serial
for (int i = 0; i < AUDIO_SAMPLE_RATE*RECORD_LENGTH_S; i++) {
printf("%d: %d\n",i, full_record[i]);
sleep_ms(2);
}
printf("dummy loop --- \n");
while(1){
}
return 0;
}
I am using a different analog microphone, not the one suggested in this example. Note that I have changed
.bias_voltage = 0.0,
I am recording 10 seconds of audio at 8000 Hz entirely in memory, then sending all the recorded audio samples to USB serial port, where I display all the data in putty as well as save as putty log file. I use this log file to regenerate audio in the PC.
If I play back the audio samples in matlab the sound is very fast (only high speed, not high pitch), and sounds as though some audio samples are being skipped. Since the number of audio samples matches what I expect, it seems the skipping is happening at the ADC itself. Could you please give me some hints on how to fix this?
I have uploaded a sample of my recording here: https://soundcloud.com/user-202091011/pico-mic-rec-01-samsung-galaxy-s7-over-the-horizon-2016
The sound volume is a bit low but my main problem is the speed of the playback and the audio frames being skipped
The original sound is Samsung galaxy s7 over the horizon (2016): https://www.youtube.com/watch?v=SyJyB2niF3s