netengineer
New member
------------------------------------
Admin Edit: ICS-52000 microphones do not appear to work well with Teensy at 44100 Hz sample rate.
------------------------------------
Hi. Is there any way to retrieve recording from the channel of each microphone?
I am looking to get the recording of individual microphones from a daisy chain connection
I am using daisy chain of 3 mics ( ICS-52000) with a Teensy 3.6.
I am currently using the latest code from member amperwest1
https://forum.pjrc.com/threads/5341...-with-Invensense-ics-52000?highlight=ics52000
But I am getting very weird results from the raw files when exported to Audacity.
I was speaking to directly to the 3 mics individually during the recording, but the only channel that displays a change in amplitude is always the same channel.

Admin Edit: ICS-52000 microphones do not appear to work well with Teensy at 44100 Hz sample rate.
------------------------------------
Hi. Is there any way to retrieve recording from the channel of each microphone?
I am looking to get the recording of individual microphones from a daisy chain connection
I am using daisy chain of 3 mics ( ICS-52000) with a Teensy 3.6.
I am currently using the latest code from member amperwest1
https://forum.pjrc.com/threads/5341...-with-Invensense-ics-52000?highlight=ics52000
Code:
#if F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000
// PLL is at 96 MHz in these modes
#define MCLK_MULT 4
#define MCLK_DIV 17
#elif F_CPU == 72000000
#define MCLK_MULT 16
#define MCLK_DIV 51
#elif F_CPU == 120000000
#define MCLK_MULT 16
#define MCLK_DIV 85
#elif F_CPU == 144000000
#define MCLK_MULT 8
#define MCLK_DIV 51
#elif F_CPU == 168000000
#define MCLK_MULT 16
#define MCLK_DIV 119
#elif F_CPU == 180000000
#define MCLK_MULT 32
#define MCLK_DIV 255
#define MCLK_SRC 0
#elif F_CPU == 192000000
#define MCLK_MULT 2
#define MCLK_DIV 17
#elif F_CPU == 216000000
#define MCLK_MULT 16
#define MCLK_DIV 153
#define MCLK_SRC 0
#elif F_CPU == 240000000
//#define MCLK_MULT 8 //original for 44.1kHz
//#define MCLK_DIV 85
#define MCLK_MULT 8 //edit for 10kHz sample
#define MCLK_DIV 375
//#define MCLK_MULT 32 //edit for 8kHz sample
//#define MCLK_DIV 1875
//#define MCLK_MULT 4 //edit for 5kHz sample
//#define MCLK_DIV 375
#else
#error "This CPU Clock Speed is not supported by the Audio library";
#endif
Code:
// Record TDM input sound as raw data (16ch, Signed 24-bit little-endian PCM, 44.1kHz, little-endian) to a SD card.
// Note: Format is modified so that mics align their 24 bit data to 32 bit slots, half of the 16 bit
// channels end up being the 8 low bits, and 8 more zeros which are discarded.
//
// Hardware:
// Mic Pin 6 (SD_O) to Teensy Pin 13 SDATA (Input, 11.3 Mbit/sec)
// Mic Pin 8 (SCK_I) to Teensy Pin 9 SCK (Output, 11.3 MHz, Checked)
// Mic Pin 10 (WS_I) to Teensy Pin 23 FS (Output, 44100 Hz, Checked)
//
// Mic GND Pins (1, 3, 5, 7 and 9) to Teensy GND
// Mic VDD to Teensy 3.3V
// At startup of the ICS-52000, the start of the frame sync (WS_I) signal should be delayed from the start of the serial clock (SCK_I) by at
// least 10 ms. This enables the microphone’s internal circuits to completely initialize before starting the synchronization sequence
// with other microphones in the TDM array. This delay can be implemented either by enabling the WS output (FS) on the clock master at
// least 10 ms after the SCK_I is enabled, or by externally controlling the signals given to the ICS-52000s.
//
//
// This example code is in the public domain.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioInputTDM tdm1; //xy=151,223
AudioRecordQueue queue4; //xy=416,221
AudioRecordQueue queue5; //xy=416,254
AudioRecordQueue queue6; //xy=416,287
AudioRecordQueue queue7; //xy=416,320
AudioRecordQueue queue3; //xy=417,187
AudioRecordQueue queue8; //xy=417,353
AudioRecordQueue queue2; //xy=418,154
AudioRecordQueue queue1; //xy=419,120
AudioConnection patchCord1(tdm1, 0, queue1, 0);
AudioConnection patchCord2(tdm1, 1, queue2, 0);
AudioConnection patchCord3(tdm1, 2, queue3, 0);
AudioConnection patchCord4(tdm1, 3, queue4, 0);
AudioConnection patchCord5(tdm1, 4, queue5, 0);
AudioConnection patchCord6(tdm1, 5, queue6, 0);
AudioConnection patchCord7(tdm1, 6, queue7, 0);
AudioConnection patchCord8(tdm1, 7, queue8, 0);
// GUItool: end automatically generated code
// GUItool: end automatically generated code
// Use these with the Teensy Audio Shield
//#define SDCARD_CS_PIN 10
//#define SDCARD_MOSI_PIN 7
//#define SDCARD_SCK_PIN 14
// Use these with the Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN BUILTIN_SDCARD
#define SDCARD_MOSI_PIN 11 // not actually used
#define SDCARD_SCK_PIN 13 // not actually used
// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN 4
//#define SDCARD_MOSI_PIN 11
//#define SDCARD_SCK_PIN 13
// Remember which mode we're doing
int mode = 0; // 0=stopped, 1=recording
int choice = 0;
int sample_number = 0;
unsigned int tsamplemillis = 10000;
String typeofsound;
int16_t* buffer1;
int16_t* buffer2;
int16_t* buffer3;
int16_t* buffer4;
int16_t* buffer5;
int16_t* buffer6;
int16_t* buffer7;
int16_t* buffer8;
// The file where data is recorded
File frec;
void setup() {
Serial.begin(115200);
// Audio connections require memory, and the record queue
// uses this memory to buffer incoming audio.
AudioMemory(512);
// Initialize the SD card
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
// stop here if no SD card, but print a message
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
while (!Serial);
Serial.println("Welcome to the 4-channel TDM recording test bench");
}
void loop() {
if (choice == 0) {
Serial.println("\nEnter new filename for sound archive: ");
while (!Serial.available());
typeofsound = Serial.readString();
sample_number = 0;
record(typeofsound, sample_number);
} else if (choice == 1) {
sample_number++;
record(typeofsound, sample_number);
} else {
//Do nothing
}
Serial.print("\nEnter 1 to take another sample in this archive or 0 to enter a new file archive: ");
while (!Serial.available());
choice = Serial.readString().toInt();
Serial.println(choice);
}
void record(String type, int number)
{
Serial.println("Recording " + type + String(number) + "...");
String sname = type + number + ".RAW";
String path = type + "/" + type + number + ".RAW";
startRecording(sname, path, type);
continueRecording();
stopRecording();
}
void startRecording(String sname, String path, String type)
{
int str_len = path.length() + 1;
char charpath[str_len];
path.toCharArray(charpath, str_len);
if (SD.exists(charpath)) {
// The SD library writes new data to the end of the
// file, so to start a new recording, the old file
// must be deleted before new data is written.
SD.remove(charpath);
}
str_len = type.length() + 1;
char chartype[str_len];
type.toCharArray(chartype, str_len);
if (!SD.exists(chartype)) {
SD.mkdir(chartype);
}
frec = SD.open(charpath, FILE_WRITE);
if (frec) {
Serial.println("File Open");
}
}
void continueRecording() {
int data = 0, num = 0;
elapsedMillis recordingTime = 0;
queue1.begin();
queue2.begin();
queue3.begin();
queue4.begin();
queue5.begin();
queue6.begin();
queue7.begin();
queue8.begin();
mode = 1;
while (recordingTime < tsamplemillis)
{
data = queue1.available();
if (data > 0)
{
buffer1 = queue1.readBuffer(); //read all queue buffers in sets of 128 16bit num
buffer2 = queue2.readBuffer();
buffer3 = queue3.readBuffer();
buffer4 = queue4.readBuffer();
buffer5 = queue5.readBuffer();
buffer6 = queue6.readBuffer();
buffer7 = queue7.readBuffer();
buffer8 = queue8.readBuffer();
queue1.freeBuffer(); //free queue buffers to allow system to re issue storage
queue2.freeBuffer();
queue3.freeBuffer();
queue4.freeBuffer();
queue5.freeBuffer();
queue6.freeBuffer();
queue7.freeBuffer();
queue8.freeBuffer();
if (data > 48) //test if queue buffers are getting too full, the serial write will probably cause a back log if it does happen.
{
Serial.write('.'); //dots in the serial monitor mean that the system isnt processing data fast enough
}
for (int i = 0; i < 128; i ++) //write data to sd card in 24bit signed pcm format (i think) (audacity seems to accept it)
{ //frames are built of 2 16 bit numbers where only 24 bits are useful, so only 3 bytes are saved to save space. Frames are little endian
frec.write(highByte(buffer2[i])); // LSB //<---------------------sample 1---------------------><---------------------sample n--------------------->
frec.write(lowByte(buffer1[i])); // Middle Byte //<----ch1----><----ch2----><----ch3----><----ch4----><----ch1----><----ch2----><----ch3----><----ch4---->
frec.write(highByte(buffer1[i])); // MSB //<LSB-MID-MSB><LSB-MID-MSB><LSB-MID-MSB><LSB-MID-MSB><LSB-MID-MSB><LSB-MID-MSB><LSB-MID-MSB><LSB-MID-MSB>
frec.write(highByte(buffer4[i])); // LSB
frec.write(lowByte(buffer3[i])); // Middle Byte
frec.write(highByte(buffer3[i])); // MSB
frec.write(highByte(buffer6[i])); // LSB
frec.write(lowByte(buffer5[i])); // Middle Byte
frec.write(highByte(buffer5[i])); // MSB
frec.write(highByte(buffer8[i])); // LSB
frec.write(lowByte(buffer7[i])); // Middle Byte
frec.write(highByte(buffer7[i])); // MSB
num++;
}
}
}
queue1.end(); //stop the background sampling
queue2.end();
queue3.end();
queue4.end();
queue5.end();
queue6.end();
queue7.end();
queue8.end();
Serial.print("num of samples written per channel:");
Serial.println(num);
}
void stopRecording() {
Serial.println("Finished recording.");
queue1.end();
queue2.end();
queue3.end();
queue4.end();
queue5.end();
queue6.end();
queue7.end();
queue8.end();
queue1.clear();
queue2.clear();
queue3.clear();
queue4.clear();
queue5.clear();
queue6.clear();
queue7.clear();;
queue8.clear();
frec.close();
mode = 0;
}
But I am getting very weird results from the raw files when exported to Audacity.
I was speaking to directly to the 3 mics individually during the recording, but the only channel that displays a change in amplitude is always the same channel.

Last edited by a moderator: