Cheap ICS-52000 Microphone Array Board for TDM evaluation

Status
Not open for further replies.

Mr.Pedro

Active member
How to format TDM data from cheap ICS-52000 Microphone Array Board?

------------------------------------
Admin Edit: ICS-52000 microphones do not appear to work well with Teensy at 44100 Hz sample rate.
------------------------------------


Hi folks,

I recently found a relatively cheap (not so much after shipping and custom fees to Europe) ICS-52000 Microphone Array Board. You can find it here. I have 2 of them daisy chained for a total of 8 Microphones.

NW_AUD_ICS52000.png

I was planning to use this USB streamer which costed me more than 150$ after shipping and custom fees. However, after receiving it and checking myself the TDM specifications that were not clearly provided in the datasheet I've found it it's not compatible with the ICS-52000 microphones. Audio data is not shifted in the appropriate timing, so sad.

Now, I do need a fast solution for evaluating the microphones, so here we have Teensy 3.6 (I'm lately planning to move to a SHARC DSP).

I'm planning to simply record all 16x16-bit channels using tdm and queue objects (based on Recorder example) in a SD card (RAW format), to lately process the data into 8x32 bits channels using Matlab/Python.

Ideally I was planning to be able to stream all 8x32 bits channel via a USB Audio Interface for real-time processing on Python using ASIO drivers, but I don't think this is an option with current usb object on Teensy.

Can you foreseen any limitation or problems?

I'll post my progress here, thank you,
Pedro
 
Last edited by a moderator:
Looks interesting. I ordered 2 of them. Don't know when I'll actually do anything with them, if ever...
Happy new year but meanwhile...

I'm trying to get 1 channel of 24 bits PCM Audio Data at 44.1KHz from 2 NW-AUD-ICS52000 boards connected in the same bus (8 Microphones) based on TDM and queue objects using a modified version of the Recorder example.

abb50072634bbdd3a32fb5976e0b9d49.png

Code:
// Record TDM input sound as raw data (16ch, Signed 16-bit PCM, 44.1kHz, little-endian) to a SD card.
// Note: Need to modify format, mics align their 24 bit data to 32 bit slots, so half of the 16 bit
// channels will end up being the 8 low bits, and 8 more zeros.
//
// Hardware:
//   Pin  9 SCLK  (Output, 11.3 MHz, Checked)
//   Pin 13 SDATA (Input, 11.3 Mbit/sec)
//   Pin 23 FS    (Output, 44100 Hz, Checked)
//
// This example code is in the public domain.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=359,317
//AudioRecordQueue         queue13;        //xy=620,615
//AudioRecordQueue         queue14;        //xy=620,649
//AudioRecordQueue         queue15;        //xy=620,682
//AudioRecordQueue         queue12;        //xy=621,581
//AudioRecordQueue         queue16;        //xy=622,716
//AudioRecordQueue         queue9;         //xy=623,480
//AudioRecordQueue         queue10;        //xy=623,514
//AudioRecordQueue         queue11;        //xy=623,547
//AudioRecordQueue         queue4;         //xy=624,315
//AudioRecordQueue         queue5;         //xy=624,348
//AudioRecordQueue         queue6;         //xy=624,381
//AudioRecordQueue         queue7;         //xy=624,414
//AudioRecordQueue         queue3;         //xy=625,281
//AudioRecordQueue         queue8;         //xy=625,447
AudioRecordQueue         queue2;         //xy=626,248
AudioRecordQueue         queue1;         //xy=627,214
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);
//AudioConnection          patchCord9(tdm1, 8, queue9, 0);
//AudioConnection          patchCord10(tdm1, 9, queue10, 0);
//AudioConnection          patchCord11(tdm1, 10, queue11, 0);
//AudioConnection          patchCord12(tdm1, 11, queue12, 0);
//AudioConnection          patchCord13(tdm1, 12, queue13, 0);
//AudioConnection          patchCord14(tdm1, 13, queue14, 0);
//AudioConnection          patchCord15(tdm1, 14, queue15, 0);
//AudioConnection          patchCord16(tdm1, 15, queue16, 0);
AudioControlSGTL5000     sgtl5000_1;     //xy=369,479
// 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 = 11000;

String typeofsound;

// The file where data is recorded
File frec;

void setup() {
  
  Serial.begin(9600);

  // Audio connections require memory, and the record queue
  // uses this memory to buffer incoming audio.
  AudioMemory(60);

  // Enable the audio shield, select input, and enable output
  sgtl5000_1.enable();

  // 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 beta version of Viband's TDM sound recorder, 11 second clips are going to be recorded, be \ncareful introducing a new type of sound already introduced since previous samples will be overwritten.");
  Serial.println("\nNote: SD Library uses short 8.3 names (12 characters). Filename (i.e baby/baby24) can't be longer.");
}

void loop() {

  if(choice==0){
  Serial.println("\nIntroduce new type of sound (i.e baby): ");
  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("\nIntroduce 1 to take another sample or 0 to introduce a new type of sound: ");
  while(!Serial.available());
  choice = Serial.readString().toInt();
  Serial.println(choice);
    
}

void record(String type, int number){
  Serial.println("Recording " + type + String(number) + "...");
  elapsedMillis recordingTime = 0;
  String sname = type + number + ".RAW";
  String path = type + "/" + type + number + ".RAW";
  startRecording(sname, path, type);  
  while(recordingTime<tsamplemillis) 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");
    queue1.begin();
    queue2.begin();
//    queue3.begin();
//    queue4.begin();
//    queue5.begin();
//    queue6.begin();
//    queue7.begin();
//    queue8.begin();
//    queue9.begin();
//    queue10.begin();
//    queue11.begin();
//    queue12.begin();
//    queue13.begin();
//    queue14.begin();
//    queue15.begin();
//    queue16.begin();
    mode = 1;
  }
}

void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    byte buffer[512];
    byte buffer1[256];
    byte buffer2[256];
    // Fetch 2 blocks from the audio library and copy
    // into a 512 byte buffer.  The Arduino SD library
    // is most efficient when full 512 byte sector size
    // writes are used.
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    int b = 0;
    for(int i = 0; i < 512; i += 2){
        buffer[i] = buffer1[b];
        buffer[i + 1] = buffer2[b];
        b++;
    }
    // write all 512 bytes to the SD card
    //elapsedMicros usec = 0;
    frec.write(buffer, 512);
    // Uncomment these lines to see how long SD writes
    // are taking.  A pair of audio blocks arrives every
    // 5802 microseconds, so hopefully most of the writes
    // take well under 5802 us.  Some will take more, as
    // the SD library also must write to the FAT tables
    // and the SD card controller manages media erase and
    // wear leveling.  The queue1 object can buffer
    // approximately 301700 us of audio, to allow time
    // for occasional high SD card latency, as long as
    // the average write time is under 5802 us.
    //Serial.print("SD write, us=");
    //Serial.println(usec);
  }
}

void stopRecording() {
  Serial.println("Finished recording.");
  queue1.end();
  queue2.end();
  queue1.clear();
  queue2.clear();
  frec.close();  
  mode = 0;
}

I'm using queue1 and queue2 to get the first 2x 16 bit objects which are supposed to contain the 24 bit audio data and 8 more zero in the 8 low bits.

The way I'm interleaving the 2 queue objects when writing to the SD file is shown in the code:

Code:
void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    byte buffer[512];
    byte buffer1[256];
    byte buffer2[256];
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    int b = 0;
    for(int i = 0; i < 512; i += 2){
        buffer[i] = buffer1[b];
        buffer[i + 1] = buffer2[b];
        b++;
    }
    frec.write(buffer, 512);
  }
}

I was expecting to obtain 32-bit sample which look (in hexadecimal) like this:
XX XX XX 00

However, using Sublime Text with Hexadecimal Encoding this is what I get:

96b63031c59c4a6b9b35c0dd65dd6679.png

In comparison to a 16-bit PCM Audio Data Raw File obtained using Teensy Audio Board, an analog Microphone and Teensy Recorder example:

aa3ce682d9dd1c2ee13647efe01a7828.png

1. How to interpret the 16-bit PCM Audio Data Raw File? (I can see a pattern of 8 data bits and 8 bits containing all zeros 00, or all 1s ff)
2. How to interpret the 32-bit blocks from the TDM bus if they are correct?


I want to use Python/Matlab to properly format the data to Signed 24-bit PCM Big/Little endian 1 channel mono to open with Audacity.

3. How does this format (Signed 24-bit PCM Big/Little endian 1 channel mono) should look? (i.e 24-bit blocks of raw audio data or 32-bit blocks with 8 zeros in the low 8 bits) I would highly appreciate if someone can share a diagram of how the format should look like. I've not been able to find a good one.

You can download the RAW files from here:
https://drive.google.com/open?id=12GT2G5wK09f-Ln3J_QXZg6tlekg5EODD

Thanks all,
Pedro
 
Last edited:
Code:
void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    byte buffer[512];
    byte buffer1[256];
    byte buffer2[256];
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    int b = 0;
    for(int i = 0; i < 512; i += 2){
        buffer[i] = buffer1[b];
        buffer[i + 1] = buffer2[b];
        b++;
    }
    frec.write(buffer, 512);
  }
}

This code is probably not what you want. You're composing the output by interleaving 8 bit bytes from each of the 2 buffers. But those 2 buffers are 16 bit samples. Treating the data as bytes will result in the original 32 bit data (pairs of 16 bits) scrambled up in a rather odd way.

You probably meant to create buffer1 and buffer2 like this:

Code:
    uint16_t buffer1[128];
    uint16_t buffer2[128];

Since you're creating 32 bit outputs back from the pairs of 16, the output buffer probably should be defined this way:

Code:
    uint32_t buffer[128];

Then you need to create a loop which reassembles the 32 bit data from each pair of 16 bit numbers, instead of just scrambling it all as interleaved bytes. Maybe like this:

Code:
    for(int i = 0; i < 128; i ++){
        buffer[i] = (buffer1[i] << 16) | buffer2[i];
    }

If this ends up with each word backwards, just swap buffer1 and buffer2 so buffer2's data ends up in the most significant half of each 32 bit word.

Hope this all makes good sense?
 
You are right, I missed with the buffer sizes.

Now, I'm using the following code which just uses a pair of 16-bit buffers to directly write to the SD with the proper interleaving:
Code:
void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    uint16_t buffer1[128];
    uint16_t buffer2[128];
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    for(int i = 0; i < 128; i ++){
        frec.write(buffer1[i]>>8);
        frec.write(buffer1[i]);
        frec.write(buffer2[i]>>8);
        frec.write(buffer2[i]);
    }
  }
}

When testing individually recording only buffer1 and buffer2 to ease the visualization I get:
buffer1 contains either FFFX or 000X:
Code:
fffd fffe ffff fffe fffe fffe fffe ffff
fffe fffe fffd fffe ffff ffff fffe fffe
fffe fffe fffd fffd fffe fffe fffe fffe
fffe fffe fffe ffff ffff ffff ffff ffff
0000 0000 0000 0000 ffff 0000 ffff 0000
0000 0001 0000 0001 0001 ffff 0000 0000
0000 ffff 0000 0000 0000 0000 ffff 0001
ffff 0000 0000 0000 0001 0000 0001 0000
ffff ffff ffff 0000 0000 0001 0001 0001
buffer2 contains either XX00 or XXc0:
Code:
33c0 6c00 1e00 3a00 9bc0 f600 adc0 5400
23c0 5bc0 b5c0 37c0 c3c0 ac00 29c0 41c0
e000 dbc0 fbc0 c5c0 d000 fc00 d5c0 2dc0
9c00 89c0 3400 d000 dc00 17c0 d1c0 1a00
3a00 2200 b9c0 fdc0 e7c0 6c00 2e00 e9c0
8200 3000 edc0 dc00 7200 b000 6a00 49c0
5e00 a600 cdc0 ffc0 d000 3c00 2200 3e00
77c0 c600 4200 cc00 a5c0 61c0 ba00 e1c0
61c0 bbc0 13c0 d200 21c0 8e00 f5c0 f200
2dc0 2bc0 0400 d000 5200 f800 f600 adc0

1. Are buffer1 and buffer2 correct?
2. How should a single Signed 24-bit PCM sample look like?


Again, referring to the original Recorder example and using an analog microphone I'm trying to understand Signed 16-bit PCM Raw Audio data format:
Code:
caff b1ff a0ff a2ff a7ff acff a4ff 9dff
a7ff b7ff c9ff c4ff bbff bbff c9ff deff
f6ff 1700 3800 4a00 5100 4b00 4100 3d00
3000 2e00 2000 0100 e4ff daff daff d2ff
d2ff cbff bbff b4ff b9ff b7ff bdff d2ff
f1ff 1200 3500 4c00 5e00 6d00 7b00 8900
8800 8b00 9900 9f00 9e00 9600 8000 6300
4800 2200 0200 feff fcff 0c00 1600 2e00
3800 3900 2600 1000 fcff e7ff cdff b7ff

3. Shouldn't it contain 16 bits of data (i.e XXXX) instead of 8 bits of data and either FF or 00 (i.e XXFF or XX00)
 
Last edited:
Again, referring to the original Recorder example and using an analog microphone I'm trying to understand Signed 16-bit PCM Raw Audio data format:
Code:
caff b1ff a0ff a2ff a7ff acff a4ff 9dff
a7ff b7ff c9ff c4ff bbff bbff c9ff deff
f6ff 1700 3800 4a00 5100 4b00 4100 3d00
3000 2e00 2000 0100 e4ff daff daff d2ff
d2ff cbff bbff b4ff b9ff b7ff bdff d2ff
f1ff 1200 3500 4c00 5e00 6d00 7b00 8900
8800 8b00 9900 9f00 9e00 9600 8000 6300
4800 2200 0200 feff fcff 0c00 1600 2e00
3800 3900 2600 1000 fcff e7ff cdff b7ff

3. Shouldn't it contain 16 bits of data (i.e XXXX) instead of 8 bits of data and either FF or 00 (i.e XXFF or XX00)

This looks "normal" for a very small signal, assuming whatever you're using to print the data as HEX is showing the bytes in the order they occur in the file (LSB first).

9f00 -> 159

a2ff -> -97

Maybe if you turn up the mic gain, or just provide stronger sound input to the mic, you'll see 16 bit data spanning a wider numerical range?
 
This looks "normal" for a very small signal, assuming whatever you're using to print the data as HEX is showing the bytes in the order they occur in the file (LSB first).

9f00 -> 159

a2ff -> -97

Maybe if you turn up the mic gain, or just provide stronger sound input to the mic, you'll see 16 bit data spanning a wider numerical range?

Thank you for the note which has helped me understanding Raw Audio Format.

Signed 24-bit little-endian PCM code:
Code:
void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    uint16_t buffer1[128];
    uint16_t buffer2[128];
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    for(int i = 0; i < 128; i ++){
        frec.write(buffer2[i]>>8); // LSB
        frec.write(buffer1[i]); // Middle Byte
        frec.write(buffer1[i]>>8); // MSB       
        //frec.write(buffer2[i]); // Zeros
    }
  }
}

Beginning of RAW File example:
Code:
bc00 002d ffff 57ff ff42 0000 5cff ffb1
ffff 6eff ff5f ffff eaff ff05 ffff dffe
ffe0 ffff 34ff ff49 ffff f0ff fffb fdff
08fe ff19 0000 5bff ff5c 0100 98ff ff69
ffff 9afe ffe8 feff d9fe ffd4 feff b0fe
ff85 feff b2fe ff7e ffff 4efe ff51 fcff
46fd ffd9 feff f7fc ff90 fdff dbfd ff9c
fdff 8ffe ffd3 fdff a1fc ffea ffff befd
ff2b fdff 5efe ff40 feff 33ff ff70 fdff
66fe ff3c fdff c8fe ff2d fdff fefd ff73
fdff c2fd ff4d fcff d700 0050 fdff 51fe
ffdd ffff 5ffe ff18 ffff e7ff ffba ffff
1fff ff7b ffff 57fd ffcf feff 02fe ff14
feff 9ffe ff1b fdff a2fd ffe3 feff abfd
ffa8 fcff 20fd ff76 feff 75fe ff59 feff
e5fe ff73 feff 82ff fff1 fdff fefe ff8b

First sample: bc0000 = 188
Second sample: 2d ffff = -211
...

File data seems correct and matches the designed interleaving and writing, however, when importing using Audacity as Raw Data... Signed 24-bit PCM, Little-endian, 1 Channel (Mono), Sample rate: 44100 Hz, this is what I get:
01e56d9d45791349b6a971d3a8e70552.jpg

Also, when writing only the LSB and the low 8 zero bits I don't always get 00 but it flips between 00 and c0:
Code:
63c0 6800 3bc0 7200 b600 5200 8200 47c0
fe00 abc0 65c0 25c0 3200 8fc0 8000 37c0
5bc0 f1c0 1fc0 8800 5800 b000 e1c0 3bc0
fdc0 7bc0 63c0 5fc0 f9c0 3bc0 dbc0 7800
87c0 65c0 0dc0 03c0 01c0 3800 a200 ae00
fe00 b400 c9c0 9c00 4a00 9600 8c00 fe00
79c0 0c00 b3c0 1dc0 a7c0 c9c0 5200 ce00
3dc0 61c0 cdc0 be00 6000 17c0 91c0 5800
aa00 2a00 55c0 25c0 e200 a1c0 7800 87c0

1. Is my assumption about how Signed 24-bit PCM data should look like correct?

PS. When increasing Audacity gain to +36dB it seems I can hear some of the knocks I'm doing in a bell, I'll continue checking this in case it's a microphone/microphone gain issue.
 
Last edited:
Maybe you should first concentrate on getting the hardware working and mic gain set appropriately?

It's very easy to just put the DAC output on the design and route the 16 bit signal to also drive the DAC. Then you can connect the DAC to an amplifier and headphones or a speaker (which hopefully doesn't feed back into the mic - headphones are much safer) and listen to actually hear whether the audio is correct and the level is reasonable.

Or you can put the USB output into your design and set Tools > USB Type to Audio, and then capture the 16 bit data with audacity. But I personally prefer getting a real analog signal and actually listening with headphones. There is much your ears can tell you instantly that gets lost in the complexity of viewing numbers and waveforms.
 
Maybe you should first concentrate on getting the hardware working and mic gain set appropriately?

It's very easy to just put the DAC output on the design and route the 16 bit signal to also drive the DAC. Then you can connect the DAC to an amplifier and headphones or a speaker (which hopefully doesn't feed back into the mic - headphones are much safer) and listen to actually hear whether the audio is correct and the level is reasonable.

Or you can put the USB output into your design and set Tools > USB Type to Audio, and then capture the 16 bit data with audacity. But I personally prefer getting a real analog signal and actually listening with headphones. There is much your ears can tell you instantly that gets lost in the complexity of viewing numbers and waveforms.
You are right about the hardware test, upon my hardware availability I've tested USB output, capturing the 16 bit data with audacity, the result is similar. I need to increase gain to 36dB to be able to roughly identify really loud and close noises to the microphone.

Also, I've read the Signed 24 bit little-endian PCM 44.1 KHz Raw File using Pyhton to ease the visualization of the analog signal and to perform frequency domain analysis to see if the signal contains data so that it's only a mic gain problem:
Code:
x, fs = sf.read(path, dtype='int32', channels=1, samplerate=44100, format='RAW', endian='LITTLE', subtype='PCM_24')
    x = x / 8388608

[-1,1) Analog signal (note maximum value is 0.06):
dfaa08e7de788ed9f27e0f54d8c36849.png

STFT (just noise, it should contain dominant frequencies at 2500, 5000, 7500Hz...):
246ac1ee2e3857dfc735c19602ee22f0.png

I'm posting at invensense forum since I believe it's a microphone issue. I've also tried channel 2, same result.

Thank you,
Pedro
 
Last edited:
You probably have already looked but I posted the code that got my ICS-52000 mics to work. I received help from Paul and others last year to get my project going. the code is towards the bottom of page 2. https://forum.pjrc.com/threads/42894-Time-division-Multiplexing(TDM)-for-multilateration(TDOA)-using-mics-from-invensense/page2?highlight=ics-52000
the problem you might have with it is that it only takes a few queues worth of data points and prints the raw values to the serial monitor. You want the streaming audio instead right? I am trying to revive this project now and would also benefit from hearing the audio that it collects(Paul recommended that I listen to the audio to make sure it's collecting good data). I want to work with you to get the audio stream. how can I help?
 
You probably have already looked but I posted the code that got my ICS-52000 mics to work. I received help from Paul and others last year to get my project going. the code is towards the bottom of page 2. https://forum.pjrc.com/threads/42894-Time-division-Multiplexing(TDM)-for-multilateration(TDOA)-using-mics-from-invensense/page2?highlight=ics-52000
the problem you might have with it is that it only takes a few queues worth of data points and prints the raw values to the serial monitor. You want the streaming audio instead right? I am trying to revive this project now and would also benefit from hearing the audio that it collects(Paul recommended that I listen to the audio to make sure it's collecting good data). I want to work with you to get the audio stream. how can I help?
I want to record and later, if possible, stream, raw audio data (Signed 24-bit little-endian PCM).

I've already unsuccessfully tried to listen to the audio by streaming only the first 16-bit tdm object, same you did in your plotter. Remember to select Audio USB Type when uploading, you can use Audacity to listen to it: https://github.com/pemarloop/teensy-tools/blob/master/PlayerUSB_TDM/PlayerUSB_TDM.ino I've also used python (see previous comments) to check data is meaningful, it's not.

When recording, I use two 16-bit objects so that I align the 24 bit data and discard the 8 low zero bits. However, signal level after normalization is very low (0.05/1), it contains mostly white noise although some loud and close sounds can be guessed as peaks: https://github.com/pemarloop/teensy-tools/blob/master/Recorder_TDM/Recorder_TDM.ino

Topic at Invensense forum with more information: https://www.invensense.com/develope...-working-properly-noisy-and-low-level-signal/

Notice your plotted signal level is also very low since you are only using the first 16 bits.

Can you test Recorder_TDM.ino with your hand wired microphone to check it's not a hardware failure? I'm using this breakout boards: https://www.notwired.co/ProductDetail/NWAUDICS52000-NotWired-CO/605574/?ProdId=605574&

I'm sending you a private message so that we can work closer and then share our progress here ;)
 
I was able to use the code working that you used for recording, I was able to import the raw audio to audacity using 24bit signed pcm, little endian, 2ch (stereo), 20500 Hz custom sample rate (this was unexpected, as I thought we should be sampling at 44100Hz, but it was needed to slow the playback speed to a correct 11 second sample). here is a link to the file I recorded:https://drive.google.com/open?id=17NJ5x3j5L3UIyOLBgA6J8sE5mNx-ngDE
I had to turn the gain up by 30db though for it to be a reasonable level. the sample rate that the mics are sending is at (44110 +- 20)Hz so I'm not sure why the recorded audio is missing over half of the samples. anyone?

edit: I figured it out, I am spliting the mono signal into stereo and thus the (sample rate)/2.
 
Last edited:
I was able to use the code working that you used for recording

dreggory, did you need to make any modifications to the .ino file posted by Pedro? https://github.com/pemarloop/teensy-tools/blob/master/Recorder_TDM/Recorder_TDM.ino I am unable to get anything more than a low gain signal that sounds like static using Pedro's Recorder_TDM.ino file. I would also like to make recordings with these microphones and save them to a file.

I'm importing the .RAW file into Audacity as Signed 24-bit PCM, Little-endian, Mono, 44100 Hz sample rate. I'm using the same ICS-52000 notwired.co board with a Teensy 3.6 at 180 MHz.

Pin connections:
Mic pin 6 (SD_O) to Teensy pin 13 (RX)
Mic pin 8 (SCK_I) to Teensy pin 9 (BCLK)
Mic pin 10 (WS_I) to Teensy pin 23 (FS)
(GND to GND, VCC to VCC)

I suspect something is wrong with the way that the data is being written from the buffers and "interleaved." Looking at the below section of the code in the for loop of continueRecording(), the following is my understanding:
1. The least significant byte, which is buffer2 shifted right by 8 bits, is written to the file first
2. The entire contents of buffer1 is written to the file
3. The most significant byte, which is buffer1 shifted right by 8 bits, is written to the file
Is that correct?

Code:
void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    uint16_t buffer1[128];
    uint16_t buffer2[128];
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    for(int i = 0; i < 128; i ++){
        frec.write(buffer2[i]>>8); // LSB
        frec.write(buffer1[i]); // Middle Byte
        frec.write(buffer1[i]>>8); // MSB       
        //frec.write(buffer2[i]); // Zeros
    }
  }
}

Any help would be appreciated.

Thanks,
Miles
 
Last edited:
Did you also give vcc to the config pin?
Edit: Nevermind it looks like the pcb does that for you. Did you turn the gain up as high as audacity will let you? Both the main volume, and channel gain.
I would check my wiring but I have it at school right now. I'll check on monday and let you know if I did anything different from what you did. Also, I didn't have to change the code.
 
Last edited:
Hi Miles,

I'm importing the .RAW file into Audacity as Signed 24-bit PCM, Little-endian, Mono, 44100 Hz sample rate. I'm using the same ICS-52000 notwired.co board with a Teensy 3.6 at 180 MHz.

This configuration is correct, the same one I have.

Pin connections:
Mic pin 6 (SD_O) to Teensy pin 13 (RX)
Mic pin 8 (SCK_I) to Teensy pin 9 (BCLK)
Mic pin 10 (WS_I) to Teensy pin 23 (FS)
(GND to GND, VCC to VCC)

The wiring is also correct. I've modified the Hardware description in my code for clarification. Notice that, in the only reply I've got from Invensense support, they emphasized on the startup sequence. I do manually connect Teensy Pin 23 FS to Mic Pin 10 (WS_I) >10ms after connecting VDD and SCK_I pins on the Mic.

Code:
// Hardware:
//   Mic Pin 6  (SD_O)  to Teensy Pin  9 SCLK  (Output, 11.3 MHz, Checked)
//   Mic Pin 8  (SCK_I) to Teensy Pin 13 SDATA (Input, 11.3 Mbit/sec)
//   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.

I suspect something is wrong with the way that the data is being written from the buffers and "interleaved." Looking at the below section of the code in the for loop of continueRecording(), the following is my understanding:
1. The least significant byte, which is buffer2 shifted right by 8 bits, is written to the file first
2. The entire contents of buffer1 is written to the file
3. The most significant byte, which is buffer1 shifted right by 8 bits, is written to the file
Is that correct?


My intention was to write LSB first, Middle byte second and MSB last. I'm not sure about point 2 writing the entire buffer (16 bits = 2 bytes) or only one element (byte) since the buffers are declared as uint16_t. Reviewing https://www.arduino.cc/en/Reference/FileWrite, it may be necessary to use lowByte() / highByte() functions which return a single byte.

Code:
for(int i = 0; i < 128; i ++){
        frec.write(highByte(buffer2[i])); // LSB
        frec.write(lowByte(buffer1[i])); // Middle Byte
        frec.write(highByte(buffer1[i])); // MSB       
        //frec.write(lowByte(buffer2[i])); // Zeros
    }

As per a private conversation with @dreggory, the following changes have also been made:
- Remove unnecessary sgtl5000_1.enable();
- Increase AudioMemory(512);


Can anyone try this modifications? I don't have the hardware with me right now. I've pushed it to GitHub.
 
Last edited:
Thank you both for all of your suggestions, unfortunately I've tried your software changes (both Mr.Pedro's newest code on GitHub, and the older version of Mr.Pedro's code from Jan 17 on GitHub with increased audio memory and removing sgtl5000_1.enable()) and many other variations of my own, all without success. I'm still not sure how to reproduce dreggory's successful recording.

dreggory, would you mind posting your working code verbatim, just as a sanity check? Also, do you recall doing anything with connecting mic pin 10 (WS_I) after a delay?

Did you turn the gain up as high as audacity will let you? Both the main volume, and channel gain.
Yes, both, it still sounds like static noise despite me making various loud noises as I record each sample.

Also, I didn't have to change the code.
Hmm. I'm unable to get any success with the code in its original Jan 17 form (according to Mr.Pedro's GitHub commit history).

What kind of wiring solution are you using, dreggory? I'm connecting the male headers of the ICS-52000 notwired.co PCB with 8" long female-to-male jumper wires (they're cheap, typically having thin wire) to a solder-less breadboard where my Teensy 3.6 resides. Could these maybe be the problem with their narrow gauge?
jumper-wires.jpg

I've modified the Hardware description in my code for clarification. Notice that, in the only reply I've got from Invensense support, they emphasized on the startup sequence. I do manually connect Teensy Pin 23 FS to Mic Pin 10 (WS_I) >10ms after connecting VDD and SCK_I pins on the Mic.
Mr.Pedro, between programming the Teensy 3.6 via USB, starting the serial monitor, typing the desired sound name, and pressing enter to start the recording, when exactly do you manually disconnect or connect the Mic pin 10 (WS_I) from Teensy pin 23 (FS) by hand? This could likely be another part of the issue, thanks for pointing that out. Maybe later we could solve this 10ms delay in software.

My intention was to write LSB first, Middle byte second and MSB last. I'm not sure about point 2 writing the entire buffer (16 bits = 2 bytes) or only one element (byte) since the buffers are declared as uint16_t. Reviewing https://www.arduino.cc/en/Reference/FileWrite, it may be necessary to use lowByte() / highByte() functions which return a single byte.

Code:
for(int i = 0; i < 128; i ++){
        frec.write(highByte(buffer2[i])); // LSB
        frec.write(lowByte(buffer1[i])); // Middle Byte
        frec.write(highByte(buffer1[i])); // MSB       
        //frec.write(lowByte(buffer2[i])); // Zeros
    }
This above writing sequence makes more sense to me for the middle byte now, since the total bytes written I would think should be 3 (3*8=24-bits), not 4 like it was previously. But hearing that dreggory got it working without any major modifications makes me question this assumption.

Can anyone try this modifications? I don't have the hardware with me right now. I've pushed it to GitHub.
Still not working for me with hardware unfortunately. I appreciate the quick update.

One idea I tested, also with no luck, was based on a sentence in the TDM component description in PaulStoffregen's audio library GUI under NOTES: https://www.pjrc.com/teensy/gui/index.html?info=AudioInputTDM
When used with TDM devices which transmit 32 bit audio, the even numbered channels will contain the useful upper 16 bits of audio data.
Our ICS-52000 microphones transmit 24-bit audio, but require two TDM channels per microphone, which sounds similar to the above mentioned case for 32-bit output. Since it says upper bytes are on the even channel, I switched the buffers around as follows:
Code:
for(int i = 0; i < 128; i++){
        frec.write(highByte(buffer1[i])); // LSB
        frec.write(lowByte(buffer2[i])); // Middle Byte
        frec.write(highByte(buffer2[i])); // MSB
    }
So that didn't work either.

Next, I'm going to see if I can learn anything more from the Teensy Audio Recorder example sketch (intended for an I2S microphone) for our TDM microphone. (File > Examples > Audio > Recorder)
 
Yes, both, it still sounds like static noise despite me making various loud noises as I record each sample.

What kind of wiring solution are you using, dreggory? I'm connecting the male headers of the ICS-52000 notwired.co PCB with 8" long female-to-male jumper wires (they're cheap, typically having thin wire) to a solder-less breadboard where my Teensy 3.6 resides. Could these maybe be the problem with their narrow gauge?

This could be a failure point, I'm using the same notwired board, Teensy 3.6, breadboard and female-to-male jumper wires.

Mr.Pedro, between programming the Teensy 3.6 via USB, starting the serial monitor, typing the desired sound name, and pressing enter to start the recording, when exactly do you manually disconnect or connect the Mic pin 10 (WS_I) from Teensy pin 23 (FS) by hand? This could likely be another part of the issue, thanks for pointing that out. Maybe later we could solve this 10ms delay in software.
As soon as the programm starts running, the microphone is enabled through Teensy 3.3V pin, and initialized through Teensy Pin 9 SCLK, any 10ms after programming the Teensy 3.6 via USB or after opening the serial monitor I connect the Teensy pin 23 (WS) by hand. I checked Teensy Pin 9 SCLK signal using the oscilloscope.

One idea I tested, also with no luck, was based on a sentence in the TDM component description in PaulStoffregen's audio library GUI under NOTES: https://www.pjrc.com/teensy/gui/index.html?info=AudioInputTDM

Our ICS-52000 microphones transmit 24-bit audio, but require two TDM channels per microphone, which sounds similar to the above mentioned case for 32-bit output. Since it says upper bytes are on the even channel, I switched the buffers around as follows:
Code:
for(int i = 0; i < 128; i++){
        frec.write(highByte(buffer1[i])); // LSB
        frec.write(lowByte(buffer2[i])); // Middle Byte
        frec.write(highByte(buffer2[i])); // MSB
    }
So that didn't work either.

Note that Buffer1 is connected to tdm channel 0 (even), and Buffer2 is connected to tdm channel 1 (odd). So buffer1 is supposed to be the even channel. Either way, you say it doesn't work if switched.

Next, I'm going to see if I can learn anything more from the Teensy Audio Recorder example sketch (intended for an I2S microphone) for our TDM microphone. (File > Examples > Audio > Recorder)

Let me know if you make any progress, right now, only dreggory has got a working version (needing to apply 30dB gain in Audacity) and the only difference is the hardware used.
 
This is my schematic.
MicArraySchematic.png
This is what it looks like (I know, it's a rats nest).
20180312_111028.jpg
I have twisted a grounded wire around SD and SCK going from the teensy to each mic. and I put a 0.1uF cap as close to each mic as I could get. I also put a 100kOhm pull down resistor at the SD pin on the teensy side.
like Mr.Pedro said, I didn't change anything but commenting out --> sgtl5000_1.enable(); and I made AudioMemory(512); I think the extra memory allocation was needed. I just tested it now with this code:

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  9 SCLK  (Output, 11.3 MHz, Checked)
//   Mic Pin 8  (SCK_I) to Teensy Pin 13 SDATA (Input, 11.3 Mbit/sec)
//   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>

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=359,317
//AudioRecordQueue         queue13;        //xy=620,615
//AudioRecordQueue         queue14;        //xy=620,649
//AudioRecordQueue         queue15;        //xy=620,682
//AudioRecordQueue         queue12;        //xy=621,581
//AudioRecordQueue         queue16;        //xy=622,716
//AudioRecordQueue         queue9;         //xy=623,480
//AudioRecordQueue         queue10;        //xy=623,514
//AudioRecordQueue         queue11;        //xy=623,547
//AudioRecordQueue         queue4;         //xy=624,315
//AudioRecordQueue         queue5;         //xy=624,348
//AudioRecordQueue         queue6;         //xy=624,381
//AudioRecordQueue         queue7;         //xy=624,414
//AudioRecordQueue         queue3;         //xy=625,281
//AudioRecordQueue         queue8;         //xy=625,447
AudioRecordQueue         queue2;         //xy=626,248
AudioRecordQueue         queue1;         //xy=627,214
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);
//AudioConnection          patchCord9(tdm1, 8, queue9, 0);
//AudioConnection          patchCord10(tdm1, 9, queue10, 0);
//AudioConnection          patchCord11(tdm1, 10, queue11, 0);
//AudioConnection          patchCord12(tdm1, 11, queue12, 0);
//AudioConnection          patchCord13(tdm1, 12, queue13, 0);
//AudioConnection          patchCord14(tdm1, 13, queue14, 0);
//AudioConnection          patchCord15(tdm1, 14, queue15, 0);
//AudioConnection          patchCord16(tdm1, 15, queue16, 0);
//AudioControlSGTL5000     sgtl5000_1;     //xy=369,479
// 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 = 11000;

String typeofsound;

// The file where data is recorded
File frec;

void setup() {
  
  Serial.begin(9600);

  // 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 beta version of Viband's TDM sound recorder, 11 second clips are going to be recorded, be \ncareful introducing a new type of sound already introduced since previous samples will be overwritten.");
  Serial.println("\nNote: SD Library uses short 8.3 names (12 characters). Filename (i.e baby/baby24) can't be longer.");
}

void loop() {

  if(choice==0){
  Serial.println("\nIntroduce new type of sound (i.e baby): ");
  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("\nIntroduce 1 to take another sample or 0 to introduce a new type of sound: ");
  while(!Serial.available());
  choice = Serial.readString().toInt();
  Serial.println(choice);
    
}

void record(String type, int number){
  Serial.println("Recording " + type + String(number) + "...");
  elapsedMillis recordingTime = 0;
  String sname = type + number + ".RAW";
  String path = type + "/" + type + number + ".RAW";
  startRecording(sname, path, type);  
  while(recordingTime<tsamplemillis) 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");
    queue1.begin();
    queue2.begin();
//    queue3.begin();
//    queue4.begin();
//    queue5.begin();
//    queue6.begin();
//    queue7.begin();
//    queue8.begin();
//    queue9.begin();
//    queue10.begin();
//    queue11.begin();
//    queue12.begin();
//    queue13.begin();
//    queue14.begin();
//    queue15.begin();
//    queue16.begin();
    mode = 1;
  }
}

void continueRecording() {
  if (queue1.available() >= 2 && queue2.available() >=2) {
    uint16_t buffer1[128];
    uint16_t buffer2[128];
    memcpy(buffer1, queue1.readBuffer(), 256);
    memcpy(buffer2, queue2.readBuffer(), 256);
    queue1.freeBuffer();
    queue2.freeBuffer();
    for(int i = 0; i < 128; i ++){
        frec.write(highByte(buffer2[i])); // LSB
        frec.write(lowByte(buffer1[i])); // Middle Byte
        frec.write(highByte(buffer1[i])); // MSB       
        //frec.write(lowByte(buffer2[i])); // Zeros
    }
  }
}

void stopRecording() {
  Serial.println("Finished recording.");
  queue1.end();
  queue2.end();
  queue1.clear();
  queue2.clear();
  frec.close();  
  mode = 0;
}

and this is what it sounded like:
https://drive.google.com/file/d/1h697lgbRokRHw5ftTG4Rfx1jJFsg1zUz/view?usp=sharing
I imported the audio using --> import RAW, --> signed 24 bit PCM, little-endian, mono, 0 offset, 100% amount to import, 44100 Hz sample rate. and then I turned the channel gain to +36dB.
My impression would be to investigate the boards you and Mr.Pedro have in common, maybe there is a bad connection on it somewhere, if you have an oscilloscope it could help to look at the SD pin, triggered off of the WS pin, to even see if the mics are sending data (with the sketch I wrote they always send data when they are powered). there's also a sad chance that the process they used to solder the mics to the boards ruined the mics. Fortunately the mics are only 4 dollars each from digikey.
I hope this helped.
 
Last edited:
Reviving this old thread, to ask if anyone ever has any success with the TDM MEMS mic eval board mentioned in the OP (https://www.notwired.co/products/detail/nwaudics52000-notwired-co/605574/).

I have four of them as well as a 16-channel ICS-52000 array board from Invensense.(http://www.invensense.com/wp-conten...DM-Microphone-Array-Demo-Board-Guide-v1.0.pdf).

I am getting clean audio from the Invensense board, configured for an 8-channel TDM stream. Trying the NotWired boards, all of them produce garbled/noisy data, it sounds a lot like the example posted above by dreggory.

I've probed the clocks and data and have not seen any notable differences...triple-checked and rebuilt my wiring....Maybe some clock skew issue that may be beyond the resolution of my older Tek scope? Maybe a design issue with the NW-AUD-ICS52000 board?

Just looking for a reality check here, if anyone has used these boards successfully or unsuccessfully I would greatly appreciate hearing about it.

Thanks
 
I've also been trying to get a NW-AUD-ICS52000 board to work, but with no success. I coded up on interface to the PRU on a Beaglebone Black and I only seem to get noise out. I'm wondering if the board is bad. The digital date looks ok but there is no audio - just noise. Maybe the microphones were damaged during the manufacturing process? Has anyone had success with this board?
 
Since last post I received four new NW-AUD-ICS52000 boards, and tried them with T3.5, 3.6, and two other TDM sinks: a miniDSP MCHStreamer and an ADAU1445 eval board. Same symptioms all around. I failed trying to remove and replace the MEMS parts with new, so I designed a small two-element board and have prototypes arriving tomorrow.

Thanks for your reply chrishansen and I'll post results when I get my boards assembled...probably be a couple weeks.
 
It this connection
---------------------------------------------------
Mic Pin 6 (SD_O) to Teensy Pin 9 SCLK (Output, 11.3 MHz, Checked)
Mic Pin 8 (SCK_I) to Teensy Pin 13 SDATA (Input, 11.3 Mbit/sec)
Mic Pin 10 (WS_I) to Teensy Pin 23 FS (Output, 44100 Hz, Checked
----------------------------------------------------
correct?
 
Status
Not open for further replies.
Back
Top