Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 6 FirstFirst 1 2 3 4 ... LastLast
Results 26 to 50 of 131

Thread: Audio Recording / Logging to SD card --> microSoundRecorder

  1. #26
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    WMXZ, you are a gentleman and a scholar.

  2. #27
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by dreggory View Post
    WMXZ, you are a gentleman and a scholar.
    Not so quickly, as you may have to do the debugging!
    CAVEAT, I'm in the field, with very limited internet access. I will try to post the results, but only if I have connection.

  3. #28
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    Quote Originally Posted by WMXZ View Post
    Not so quickly, as you may have to do the debugging!
    It would be my pleasure. I have the setup ready to go. It currently works well for very short clips. I have also used an example sketch to record 11 second clips (but only with a single mic).

  4. #29
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by dreggory View Post
    It would be my pleasure. I have the setup ready to go.
    Here you go. I just uploaded an update adding the TDM mode (change in config.h) and correcting the hibernate issue discussed in other thread.
    As said, I have no means to test TDM mode here, but at least it compiles and runs without crashing.
    Note: when using 5 Microphones, you may have channel rotation issues (128 does not divide by 5 without remainder) So, every 5 audio blocks you should have the same channel sequence. let me know if there are any issues.

  5. #30
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    I was able to compile, flash and test the code, this is what it sounds like:
    https://drive.google.com/open?id=1T0...GyRmXPEAW1zk2X

    It sounds pretty jumbled. Could this be the channel rotation issue you mentioned?
    could a number of mics be defined in the configuration file and frames divided up into 32 bit blocks?
    also there were no menu configuration items, I'm still trying to read and understand how the code is setup, so maybe this is just how it is supposed to be. I checked the timing with an oscilloscope and it looks good. So it is probably just bit shuffling issues. Where should I investigate?
    Also, I noticed that the Teensy shuts down every so often, is this the hibernation issue?

  6. #31
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by dreggory View Post
    I was able to compile, flash and test the code, this is what it sounds like:
    https://drive.google.com/open?id=1T0...GyRmXPEAW1zk2X

    It sounds pretty jumbled. Could this be the channel rotation issue you mentioned?
    could a number of mics be defined in the configuration file and frames divided up into 32 bit blocks?
    also there were no menu configuration items, I'm still trying to read and understand how the code is setup, so maybe this is just how it is supposed to be. I checked the timing with an oscilloscope and it looks good. So it is probably just bit shuffling issues. Where should I investigate?
    Also, I noticed that the Teensy shuts down every so often, is this the hibernation issue?
    Thanks for file,
    I will have look into it

  7. #32
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by WMXZ View Post
    Thanks for file,
    I will have look into it

    @dreggory,
    there are a couple of issues:
    1) wav header is not correct (will change that); best is to skip the first 50 bytes, then chan 1 should be first.
    2) the microphones are clipping, looks like bad power connection, and also data connection; what is exactly your setup, can you post a picture?

    channel 1 is for half the file some low level signal, than it goes to clipping, so I think there is no rotation going on, at least there is no indication in the data.

  8. #33
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    during the same test session I used a different recording program and I verified that the microphones were configured properly. you can hear that the audio is okay.
    https://drive.google.com/open?id=1Fx...VdYIoXzFHhGc6p

    this is the code I used:
    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 (queue5.available() >= 2 && queue6.available() >=2) {
        uint16_t buffer1[128];
        uint16_t buffer2[128];
        memcpy(buffer1, queue5.readBuffer(), 256);
        memcpy(buffer2, queue6.readBuffer(), 256);
        queue5.freeBuffer();
        queue6.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.");
      queue5.end();
      queue6.end();
      queue5.clear();
      queue6.clear();
      frec.close();  
      mode = 0;
    }
    this was provided by a user here on this forum named Pedro. I think it misses samples and is limited by what it can capture. But it shows that my setup is valid.

  9. #34
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    I copied the program and will compare.
    I will have no internet the next 2/3 days so you have to wait for an answer

  10. #35
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    But that program uses only 2 channels!

  11. #36
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    It actually only uses one channel. It stitches the two 16 bit queues together after shifting out the 8 least significant bits making a 24 bit mono recording. This program also has issues, it seems to miss samples and only record 11 seconds or so. But it does show that my setup works. I also used a program that I wrote that just records 1280 samples for each of the 5 mics, it works perfectly so this shows that my microphone array is working. now I would like to record longer clips and for all 5 mics, that's where your program is needed.

  12. #37
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    427
    Maybe useful for others to know about the signal-to-noise-ratio of the whole setup:

    microSoundRecorder based on Teensy 3.6 @96MHz F_CPU without audio board using one ICS43434 digital microphone:

    * imported the recorded mono WAV-file into audacity [16-bit, little endian, mono, 48000ksps sample rate]
    * highpass filtered the file [cutoff frequency 150Hz, 48dB/octave]
    * loudest signal has an amplitude of about 1 without audible clipping/distortion
    * noise/weakest signal at an average amplitude of about 0.0007
    * 1 / 0.0007 = 1428
    * 20 * log (1428) = 63dB SNR
    * this is very close to the physically achievable SNR of the microphone, which is given in the datasheet as 65dBA

    --> so my conclusion would be that with the ICS43434 the microSoundRecorder records everything that the ICS43434 is able to pick up.

    Very nice!

    Have fun with the Teensy,

    Frank DD4WH

  13. #38
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    @dreggory
    I tried to generate a better program, that compiles, runs and does not produce rubbish.
    could you try it out?
    you can find it under the development branch on github

  14. #39
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    I will have to try it tomorrow evening.

  15. #40
    Senior Member
    Join Date
    Dec 2013
    Posts
    223
    Frank B
    post#2
    One could try to add a SPI-RAM as buffer for the SD-Card to the audio-shield. It has the same pinout as FLASH, so the existing pads will work.
    WMXZ
    post#3
    I have thought about it and have done it on another project (using T3.2), but this limits the overall bit rate to half the SPI-RAM clock rate (write to RAM and read from RAM).
    The T3.6 allows already for about 200 kB buffer, so for the 23LC1024 to be useful one needs data rates > 2 MB/s while covering 0.1 s uSD delays. As the 23LC1024 access is limited to 20 MHz, this supports up to 10 MBit/s or 1.25 MB/s data rate (write and read)
    In the absence of quad SPI (SQI) on Teensy, this results to an interesting design. I may think about it, as I have an application where 200 kB buffer is not large enough (high speed multichannel acquisition totalling a datarate of 30 MBit/s), but I still have some 23LC1024 available, so I even may try it.
    Just curious how this memory would work for a buffer: Everspin MR20H40 - 50MHz 4Mb SPI Interface MRAM https://www.everspin.com/serial-peripheral-interface
    4,194,304-bit (524.288 KB) magnetoresistive random access memory.
    @digikey Unit Price $16.17 https://www.digikey.com/product-deta...043-ND/4047456

    FEATURES:
    No write delays
    Unlimited write endurance
    Automatic data protection on power loss
    Fast, simple SPI interface, up to 50 MHz clock rate with MR20H40.
    3.0 to 3.6 Volt power supply range
    Direct replacement for serial EEPROM, Flash, and FeRAM

  16. #41
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by Chris O. View Post
    Just curious how this memory would work for a buffer: Everspin MR20H40 - 50MHz 4Mb SPI Interface MRAM https://www.everspin.com/serial-peripheral-interface
    4,194,304-bit (524.288 KB) magnetoresistive random access memory.
    @digikey Unit Price $16.17 https://www.digikey.com/product-deta...043-ND/4047456

    FEATURES:
    No write delays
    Unlimited write endurance
    Automatic data protection on power loss
    Fast, simple SPI interface, up to 50 MHz clock rate with MR20H40.
    3.0 to 3.6 Volt power supply range
    Direct replacement for serial EEPROM, Flash, and FeRAM
    It could work up to say 20 MHz (<50 MHz/2) bit clock (that is aggregated sampling rate of 1.25 MHz @16 bit, or 625 kHz @ 32 bit data words)

    how it would work:
    ACQ ISR would directly write data to MRAM
    uSD disk write part would access data von MRAM and copy to uSD
    So, for each data word the MRAM has to be accessed twice (that why throughput is half max clock rate)

    I did this with multiple 1 MBit 23LC1024 but access sped was limited to 10 MHz

  17. #42
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    Okay, I think I see improvement. Now when I import the audio to Audacity, I can see all 5 channels look like real data.
    -However, it sounds terrible. I'm just guessing, but I think that it sounds like the MSB's and the LSB's got switched or maybe shifted out.
    -I noticed that the import only worked if 32 bit sample setting was used. Just to clarify, these mics send the data from each mic in 32bit frames but only the first 24 bits are the actual sample, so there are 8 bits following each sample that must be discarded.
    -Here is a link to the folder that has the recorded audio using your latest code:
    https://drive.google.com/open?id=1gS...cA21dsd9Kk0mXS

  18. #43
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by dreggory View Post
    Okay, I think I see improvement. Now when I import the audio to Audacity, I can see all 5 channels look like real data.
    -However, it sounds terrible. I'm just guessing, but I think that it sounds like the MSB's and the LSB's got switched or maybe shifted out.
    I was off internet for a couple of days.
    I found an error that would rotate data around. I did also some minor refacturing.
    Could you please try the latest GitHub in microSoundRecorder_dev branch?

  19. #44
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    Okay sounds great. I'm still not sure why the audio has to be imported to Audacity as 32 bit float, but it works. There is some popping in each mic's tracks (isolated to a track or two, not evenly spread throughout). I think the popping may be a problem on my end, unless there is something in the code that could cause this?
    I was wondering, when I import the audio in audacity and it splits the tracks up, does it keep them in order or does it mix them up? could you could explain how Audacity splits the tracks?
    here are the latest recordings:
    https://drive.google.com/open?id=1rZ...MwFFbqbXJfdJrK

    Thank you for your excellent work. Now I can start processing!

  20. #45
    Hi WMXZ. What a wonderful project you have going here. It’s impressive how many of us are doing these things and interested in solutions that are extensible and affordable. I am really pleased to see the weather sensing in conjunction with sound recording - it will help me immensely.

    I have a system running with a single MEMS mic on a 3.6. All good. It is outdoors now to test battery life over the next few days.

    On the other hand I have had no luck getting the Tympan version to work. It compiles but if I turn it off and on again it never boots. Even if I compile to the Teensy and leave connected on USB, mothering is ever recorded and that is when leaving the time window to cover 24 hrs and making the setup standard 120, 60, 180. The console reports the loop in this case but the numbers re mostly 0. I have a Rev C board and I checked to see if the pins are correct. I am not cleare where they re defined though?

  21. #46
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by dreggory View Post
    Okay sounds great. I'm still not sure why the audio has to be imported to Audacity as 32 bit float, but it works. There is some popping in each mic's tracks (isolated to a track or two, not evenly spread throughout). I think the popping may be a problem on my end, unless there is something in the code that could cause this?
    I was wondering, when I import the audio in audacity and it splits the tracks up, does it keep them in order or does it mix them up? could you could explain how Audacity splits the tracks?
    - IMO this is a bug Audacity, or better when using 'open' (or import wav file) then the sampling frequency is correct, the data (16 bit integer) are also correct displayed (10 s audio data), but format is shown as 32 bit float (I used Audacity 2.1.3).
    - Popping, no idea where this is from, the first 3 channels are fine, the last two have similar but not identical spikes (you can see that if you zoom into a single spike)
    - splitting channels, they should be in the order they are written to disk. No, I have no idea how Audacity works. If you wanted to know which microphone is which channel, you should do the standard test, touching gently a single microphone and note on which channel it shows up.

  22. #47
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by garthpaine View Post
    I have a system running with a single MEMS mic on a 3.6. All good. It is outdoors now to test battery life over the next few days.
    You surely tell use the results, right?
    On the other hand I have had no luck getting the Tympan version to work. It compiles but if I turn it off and on again it never boots. Even if I compile to the Teensy and leave connected on USB, mothering is ever recorded and that is when leaving the time window to cover 24 hrs and making the setup standard 120, 60, 180. The console reports the loop in this case but the numbers re mostly 0. I have a Rev C board and I checked to see if the pins are correct. I am not cleare where they re defined though?
    I just ordered a Tympan, but it will need some time to arrive here.

  23. #48
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    Quote Originally Posted by WMXZ View Post
    - IMO this is a bug Audacity, or better when using 'open' (or import wav file) then the sampling frequency is correct, the data (16 bit integer) are also correct displayed (10 s audio data), but format is shown as 32 bit float (I used Audacity 2.1.3).
    I did see that it was 16 bit samples when I imported the data to octave. I am wondering why you went with 16 bit values instead of 24 bit that the ics-52000 mics send. Though it does look like it is not an issue, since I don't see any clipping. Anyway I am grateful for what I can do with your code, thank you.

  24. #49
    Member
    Join Date
    Mar 2017
    Location
    Utah
    Posts
    55
    If you wanted to know which microphone is which channel, you should do the standard test, touching gently a single microphone and note on which channel it shows up.
    I tried touching each mic to see what order they are in, and it looks like there is a problem of mixed tracks. I recorded myself saying the mic number, before touching each mic in order ("mic 1" *touch 1*, "mic 2" *touch 2*, "mic 3" *touch 3*, "mic 4" *touch 4*, "mic 5" *touch 5*).
    Here is the recorded audio:
    https://drive.google.com/open?id=1fq...pwomRa5ce7YrEK

  25. #50
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,289
    Quote Originally Posted by dreggory View Post
    I am wondering why you went with 16 bit values instead of 24 bit that the ics-52000 mics send.
    because it was supposed to be based on the audio-library, which is 16 bit.
    depending what you wanted to do, there is often no need to go to 32 bit or if you wanted 24 bit mode, so 16 bit could be sufficient.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •