Hi all, long-time Teensy tinkerer checking in here for the first time.
I'm testing a PDM microphone (SPK0641HT4H-1) using a Teensy 4.1, which is a simple implementation taking the PDM Input, applying a gain and outputting over USB as an audio device. The program works well at the default clock value of 2.8MHz, however I want to lower the frequency to 768kHz to meet the microphone's low-power requirement.
I've found a function on the forum to reduce the clock speed which works (though the input is meant to be Hz, I find specifying only '768' gives me 768kHz whereas 768000 gives a high MHz reading), but when I test this with Audacity the resulting audio is high-pitched and distorted, which I assume is because the decimation is not being changed to match this.
My question is, is there an simple way to change the PDM frequency / decimation that I may be missing here, or is it a significant effort to get this working? I should specify that I'm by no means a software engineer, and in the past I haven't had to make alterations like this, so apologies if this is a stupid question!
For reference, my current code is below.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <utility/imxrt_hw.h>
void setI2SFreq(int freq) {
// PLL between 27*24 = 648MHz und 54*24=1296MHz
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
int n2 = 1 + (24000000 * 27) / (freq * 256 * n1);
double C = ((double)freq * 256 * n1 * n2) / 24000000;
int c0 = C;
int c2 = 10000;
int c1 = C * c2 - (c0 * c2);
set_audioClock(c0, c1, c2, true);
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
| CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
| CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
}
// GUItool: begin automatically generated code
AudioInputPDM pdm1; //xy=239,348
AudioAmplifier amp1; //xy=380,347
AudioOutputUSB usb1; //xy=532,346
AudioConnection patchCord1(pdm1, amp1);
AudioConnection patchCord2(amp1, 0, usb1, 0);
AudioConnection patchCord3(amp1, 0, usb1, 1);
// GUItool: end automatically generated code
void setup() {
Serial.begin(115200);
amp1.gain(8);
AudioMemory(20);
//setI2SFreq(768);
}
void loop() {
}
Many thanks.
I'm testing a PDM microphone (SPK0641HT4H-1) using a Teensy 4.1, which is a simple implementation taking the PDM Input, applying a gain and outputting over USB as an audio device. The program works well at the default clock value of 2.8MHz, however I want to lower the frequency to 768kHz to meet the microphone's low-power requirement.
I've found a function on the forum to reduce the clock speed which works (though the input is meant to be Hz, I find specifying only '768' gives me 768kHz whereas 768000 gives a high MHz reading), but when I test this with Audacity the resulting audio is high-pitched and distorted, which I assume is because the decimation is not being changed to match this.
My question is, is there an simple way to change the PDM frequency / decimation that I may be missing here, or is it a significant effort to get this working? I should specify that I'm by no means a software engineer, and in the past I haven't had to make alterations like this, so apologies if this is a stupid question!
For reference, my current code is below.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <utility/imxrt_hw.h>
void setI2SFreq(int freq) {
// PLL between 27*24 = 648MHz und 54*24=1296MHz
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
int n2 = 1 + (24000000 * 27) / (freq * 256 * n1);
double C = ((double)freq * 256 * n1 * n2) / 24000000;
int c0 = C;
int c2 = 10000;
int c1 = C * c2 - (c0 * c2);
set_audioClock(c0, c1, c2, true);
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
| CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
| CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
}
// GUItool: begin automatically generated code
AudioInputPDM pdm1; //xy=239,348
AudioAmplifier amp1; //xy=380,347
AudioOutputUSB usb1; //xy=532,346
AudioConnection patchCord1(pdm1, amp1);
AudioConnection patchCord2(amp1, 0, usb1, 0);
AudioConnection patchCord3(amp1, 0, usb1, 1);
// GUItool: end automatically generated code
void setup() {
Serial.begin(115200);
amp1.gain(8);
AudioMemory(20);
//setI2SFreq(768);
}
void loop() {
}
Many thanks.