Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue recording with Analog microphone #17

Open
tuneado opened this issue Apr 5, 2023 · 7 comments
Open

Issue recording with Analog microphone #17

tuneado opened this issue Apr 5, 2023 · 7 comments

Comments

@tuneado
Copy link

tuneado commented Apr 5, 2023

Hey there
Thanks for this project its been very helpful and insightful so far.

I managed to adapt the project to the Arduino's SD library and got the recording workig with the MEM's microphone.. but when i hook up a MAX9814 analog mic my recording gets super slow(aprox 4x longer) i think this has to do with the bit resolution of the recording or something but im fairly 'newbie' to programing. Thats why im asking you for help

The two recordings
top - analog mic (4x the size of the bottom one)
bottom - mems microphone

Screenshot (15)

@Gaai
Copy link

Gaai commented Apr 22, 2023

Could you post all the changes you made? The code would give more insight in what could be happening than a picture of audacity waveforms. That's the result not the cause.

@tuneado
Copy link
Author

tuneado commented May 1, 2023

Could you post all the changes you made? The code would give more insight in what could be happening than a picture of audacity waveforms. That's the result not the cause.

Hey there Gaai thanks for the reply.

Apart from changing some fo the pins (with no issues on that) and transitioning to the sd library using the #9 theres not much ive changed but here is the code for:
WAVFileWritter.cpp

#include "WAVFileWriter.h"

static const char *TAG = "WAV";

WAVFileWriter::WAVFileWriter(File fp, int sample_rate)
{
  m_fp = fp;
  m_header.sample_rate = sample_rate;
  // write out the header - we'll fill in some of the blanks later
  m_fp.write((uint8_t *) &m_header, sizeof(m_header));
  m_file_size = sizeof(wav_header_t);
}

void WAVFileWriter::write(int16_t *samples, int count)
{
  // write the samples and keep track of the file size so far
  uint8_t* sampleBytes = (uint8_t*)samples;
  m_fp.write(sampleBytes, sizeof(int16_t) * count);
  m_file_size += sizeof(int16_t) * count;
}

void WAVFileWriter::finish()
{
  // now fill in the header with the correct information and write it again
  m_header.data_bytes = m_file_size - sizeof(wav_header_t);
  m_header.wav_size = m_file_size - 8;
  m_fp.seek(0);
  m_fp.write((uint8_t *) &m_header, sizeof(m_header));
}

WAVFileWritter.h

#pragma once

#include "FS.h"
#include "WAVFile.h"

class WAVFileWriter
{
private:
  int m_file_size;

  File m_fp;
  wav_header_t m_header;

public:
  WAVFileWriter(File fp, int sample_rate);
  void start();
  void write(int16_t *samples, int count);
  void finish();
};

ADCSAMPLER.cpp

#include "ADCSampler.h"

ADCSampler::ADCSampler(adc_unit_t adcUnit, adc1_channel_t adcChannel, const i2s_config_t &i2s_config) : I2SSampler(I2S_NUM_0, i2s_config)
{
    m_adcUnit = adcUnit;
    m_adcChannel = adcChannel;
}

void ADCSampler::configureI2S()
{
    //init ADC pad
    i2s_set_adc_mode(m_adcUnit, m_adcChannel);
    // enable the adc
    i2s_adc_enable(m_i2sPort);
}

void ADCSampler::unConfigureI2S()
{
    // make sure ot do this or the ADC is locked
    i2s_adc_disable(m_i2sPort);
}

int ADCSampler::read(int16_t *samples, int count)
{
    // read from i2s
    size_t bytes_read = 0;
    i2s_read(m_i2sPort, samples, sizeof(int16_t) * count, &bytes_read, portMAX_DELAY);
    int samples_read = bytes_read / sizeof(int16_t);
    for (int i = 0; i < samples_read; i++)
    {
        //samples[i] = (2048 - (uint16_t(samples[i]) & 0xfff)) * 15;
        samples[i] = (2048 - (uint16_t(samples[i]) & 0xfff)) * 15;
    }
    return samples_read;
}

ADCSampler.h

#pragma once

#include "I2SSampler.h"

class ADCSampler : public I2SSampler
{
private:
    adc_unit_t m_adcUnit;
    adc1_channel_t m_adcChannel;

protected:
    void configureI2S();
    void unConfigureI2S();

public:
    ADCSampler(adc_unit_t adc_unit, adc1_channel_t adc_channel, const i2s_config_t &i2s_config);
    virtual int read(int16_t *samples, int count);
};

@Gaai
Copy link

Gaai commented May 1, 2023

There 's a few things that don't add up to me.
uint8_t* sampleBytes = (uint8_t*)samples; m_fp.write((uint8_t *) &m_header, sizeof(m_header));

While samples is uint16_t.

Original WAVFileWriter:
void WAVFileWriter::write(int16_t *samples, int count) { // write the samples and keep track of the file size so far fwrite(samples, sizeof(int16_t), count, m_fp); m_file_size += sizeof(int16_t) * count; }

I2SMEMS (config.h: 32bit):
i2s_read(m_i2sPort, raw_samples, sizeof(int32_t) * count, &bytes_read, portMAX_DELAY); int samples_read = bytes_read / sizeof(int32_t); for (int i = 0; i < samples_read; i++) { samples[i] = (raw_samples[i] & 0xFFFFFFF0) >> 11; }

ADC (config.h 16bit):
i2s_read(m_i2sPort, samples, sizeof(int16_t) * count, &bytes_read, portMAX_DELAY); int samples_read = bytes_read / sizeof(int16_t); for (int i = 0; i < samples_read; i++) { samples[i] = (2048 - (uint16_t(samples[i]) & 0xfff)) * 15; }

Also how did you bias your input? 

@tuneado
Copy link
Author

tuneado commented May 15, 2023

There 's a few things that don't add up to me. uint8_t* sampleBytes = (uint8_t*)samples; m_fp.write((uint8_t *) &m_header, sizeof(m_header));

While samples is uint16_t.

Also how did you bias your input? 

yeah i think everything is ok with my input. i really think the issue relies on the sample units like you said.
im gonna review it and ill give you an update

@tuneado
Copy link
Author

tuneado commented May 15, 2023

There 's a few things that don't add up to me. uint8_t* sampleBytes = (uint8_t*)samples; m_fp.write((uint8_t *) &m_header, sizeof(m_header));

While samples is uint16_t.

Original WAVFileWriter: void WAVFileWriter::write(int16_t *samples, int count) { // write the samples and keep track of the file size so far fwrite(samples, sizeof(int16_t), count, m_fp); m_file_size += sizeof(int16_t) * count; }

i got this part of the code from a reply to issue #9 @

@valentasn
Copy link

valentasn commented Aug 24, 2023

@tuneado I had a completely different one. Recorded voice was super fast x2 or x3 times faster than normal. I'm using MEMS microphone INMP441 module.

image

Spend some time to figure this out, and fixed function now looks like this:

int I2SMEMSSampler::read(int16_t *samples, int count)
{
// read from i2s
int16_t *raw_samples = (int16_t *) malloc(sizeof(int16_t) * count);
size_t bytes_read = 0;
i2s_read(m_i2sPort, raw_samples, sizeof(int16_t) * count, &bytes_read, portMAX_DELAY);
int samples_read = bytes_read / sizeof(int16_t);
for (int i = 0; i < samples_read; i++)
{
samples[i] = (1024 - (uint16_t(raw_samples[i]) & 0xFFFFFFF0)) * 15;
}
free(raw_samples);
return samples_read;
}

Apparently value "15" is a gain of sound amplification.
1024 - dma_buf_len.

Adding my i2s config:

// i2s config for reading from I2S
i2s_config_t i2s_mic_Config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = (uint32_t) SAMPLE_RATE, // 40000
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = (i2s_comm_format_t) I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = 0,
.dma_buf_count = 4,
.dma_buf_len = 1024,
.use_apll = 0,
.tx_desc_auto_clear = true,
.fixed_mclk = 0
};

You are right to point out that issue relies on the sample units. Thank you!

@DJprasenjit
Copy link

Hey there Thanks for this project its been very helpful and insightful so far.

I managed to adapt the project to the Arduino's SD library and got the recording workig with the MEM's microphone.. but when i hook up a MAX9814 analog mic my recording gets super slow(aprox 4x longer) i think this has to do with the bit resolution of the recording or something but im fairly 'newbie' to programing. Thats why im asking you for help

The two recordings top - analog mic (4x the size of the bottom one) bottom - mems microphone

Screenshot (15)

hello. I wanted to use PDM microphone. Please tell me how to do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants