TDM with AK4619

Ah, sorry, you're correct, I missed the clock settings. So many registers to check :rolleyes:

It seems you are very close to getting it all working so well done and definitely get it all documented as I'm sure there are others who have been struggling with it. The AK4619 is a very good codec but darned complicated!
 
Right now it looks like I've run into a Teensy Audio bug, or I am using it wrong somehow @GuitarPhil .

I've currently got some code that outputs clean waveforms on all four output channels. The channels are set up as follows:

Code:
// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=326,427
AudioOutputTDM           tdm2;           //xy=843,411
AudioSynthWaveform       waveform1;      //xy=347,179
AudioSynthWaveform       waveform2;      //xy=347,179
AudioSynthWaveform       waveform3;      //xy=347,179
AudioSynthWaveformDc     dc1;            //xy=575,252
AudioAmplifier           amp1;           //xy=540,355

AudioConnection          patchCord5(waveform1, 0, tdm2, 0);
AudioConnection          patchCord6(waveform2, 0, tdm2, 2);
AudioConnection          patchCord7(waveform3, 0, tdm2, 4);
AudioConnection          patchCord8(waveform1, 0, tdm2, 6);

MCLK timing (20kHz sample rate):
1720551804326.png


BICK Timing (20kHz sample rate):
1720551718188.png


Full data frame with scope:

1720553218857.png
(left to right, top to bottom DAC1L, DAC1R, DAC2L, DAC2R)

1720551970066.png


If I modify that code by adding the following connections, I get dropouts on DAC1 R and DAC2 L.

Code:
// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=326,427
AudioOutputTDM           tdm2;           //xy=843,411
AudioSynthWaveform       waveform1;      //xy=347,179
AudioSynthWaveform       waveform2;      //xy=347,179
AudioSynthWaveform       waveform3;      //xy=347,179
AudioSynthWaveformDc     dc1;            //xy=575,252
AudioAmplifier           amp1;           //xy=540,355

AudioConnection          patchCord5(waveform1, 0, tdm2, 0);
AudioConnection          patchCord6(waveform2, 0, tdm2, 2);
AudioConnection          patchCord7(waveform3, 0, tdm2, 4);
AudioConnection          patchCord8(waveform1, 0, tdm2, 6);

AudioConnection          patchCord1(tdm1, 0, amp1, 0);
AudioConnection          patchCord2(amp1, 0, tdm2, 8);

Different configurations of connections seem to result in different strange behavior, but it's consistently this weird choppy waveform where I see zero data intermittently. Clock timing is consistent with what is displayed in the earlier screenshots, but you can see that the middle channel data is now missing from the Teensy output.

I realize I'm sending to a channel that the AK4619 should ignore- the reason is to demonstrate that the synthesized data on the prior channels seems to randomly go missing when I use the AudioInputTDM. Also the amp is set to gain 0, so it should result in all 0s on slot 8 and have no effect anyway. None of the problematic signals here are coming from the AK4619 (well, other than the choppy output, but that's explained by the TX output of the Teensy). This seems to be an issue with the Teensy, either how I'm using it or the TDM objects themselves?

1720552799807.png
(left to right, top to bottom DAC1L, DAC1R, DAC2L, DAC2R)

1720552546774.png


Here is the code I'm using:

C++:
#include <Wire.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <utility/imxrt_hw.h>

class AK4619 {
public:
  TwoWire* wire;
  uint8_t addr;
  void Init(uint8_t i2cAddress=0x10) {
    Wire.begin();
    addr = i2cAddress;
  }
  uint8_t writeReg(uint8_t deviceReg, uint8_t regVal) {
    Wire.beginTransmission(addr);
    Wire.write(deviceReg);
    Wire.write(regVal);
    return(Wire.endTransmission(true));
  }

  uint8_t readReg(int8_t deviceReg, uint8_t * regVal) {
    Wire.beginTransmission(addr);
    Wire.write(deviceReg);
    Wire.endTransmission(true);
    uint8_t numbytes = 0;
    numbytes = Wire.requestFrom(addr, (uint8_t)1, (uint8_t)false);
    if((bool)numbytes){
      Wire.readBytes(regVal, numbytes);
    }
    return(Wire.endTransmission(true)); //Send STOP
  }
};
 
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
//Serial.printf("SetI2SFreq(%d)\n",freq);
}

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=326,427
AudioOutputTDM           tdm2;           //xy=843,411
AudioSynthWaveform       waveform1;      //xy=347,179
AudioSynthWaveform       waveform2;      //xy=347,179
AudioSynthWaveform       waveform3;      //xy=347,179
AudioSynthWaveformDc     dc1;            //xy=575,252
AudioAmplifier           amp1;           //xy=540,355

AudioConnection          patchCord5(waveform1, 0, tdm2, 0);
AudioConnection          patchCord6(waveform2, 0, tdm2, 2);
AudioConnection          patchCord7(waveform3, 0, tdm2, 4);
AudioConnection          patchCord8(waveform1, 0, tdm2, 6);

// -------------------------------------------------------
// UNCOMMENT ME TO CAUSE ISSUES WITH DAC1R and DAC2L!!!! -
// -------------------------------------------------------
// AudioConnection          patchCord1(tdm1, 0, amp1, 0);
// AudioConnection          patchCord2(amp1, 0, tdm2, 8);

AK4619 codec;

uint8_t regval = 0;
uint8_t error = 0;
int count = 0;

void setup() {

  Serial.begin(9600);

  Serial.println("hi");

  AudioMemory(20);

  setI2SFreq(20000);

  Serial.println("begin");

  // AK4619VN startup sequence
  pinMode(41, OUTPUT);
  digitalWrite(41, LOW);
  delay(200);
  digitalWrite(41, HIGH);
  delay(200);
  codec.Init();
  delay(200);

  //if(codec.writeReg(0x00, 0b00110111)) Serial.println("Error."); // set last but repeated here for address consistency
  if(codec.writeReg(0x01, 0b11111110)) Serial.println("Error."); // set AK4619 regs
  if(codec.writeReg(0x02, 0b00011100)) Serial.println("Error.");
  if(codec.writeReg(0x03, 0b00000011)) Serial.println("Error.");
  if(codec.writeReg(0x04, 0b00100010)) Serial.println("Error.");
  if(codec.writeReg(0x05, 0b00100010)) Serial.println("Error.");
  if(codec.writeReg(0x06, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x07, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x08, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x09, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x0A, 0b00000000)) Serial.println("Error.");
  if(codec.writeReg(0x0B, 0b01010101)) Serial.println("Error.");
  //if(codec.writeReg(0x0C, 0b00000000)) Serial.println("Error."); //reserved
  if(codec.writeReg(0x0D, 0b00000000)) Serial.println("Error.");
  if(codec.writeReg(0x0E, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x0F, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x10, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x11, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x12, 0b00000100)) Serial.println("Error.");
  if(codec.writeReg(0x13, 0b00000101)) Serial.println("Error.");
  if(codec.writeReg(0x14, 0b00001010)) Serial.println("Error.");
  if(codec.writeReg(0x00, 0b00110111)) Serial.println("Error."); // turn AK4619 on

  // read back AK4619 register settings
  for(int i=0;i<=0x14;i++) {
    if(codec.readReg(i, &regval)) {
      Serial.println("READ ERROR!");
    }
    Serial.print(i, HEX);
    Serial.print(": \t");
 
    for (int8_t i = 7; i >= 0; i--) {
      uint8_t bit = (regval >> i) & 1;
      Serial.print(bit);
      if (i % 4 == 0)
        Serial.print(" ");
    }
    Serial.print("\t");
    Serial.print(regval, HEX);
    Serial.println();
  }
  Serial.println("Setup done");

  // set up waveforms
  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(30);
  waveform1.amplitude(1.0);

  waveform2.begin(WAVEFORM_SAWTOOTH);
  waveform2.frequency(30);
  waveform2.amplitude(1.0);

  waveform3.begin(WAVEFORM_TRIANGLE);
  waveform3.frequency(30);
  waveform3.amplitude(1.0);

  amp1.gain(0.0);
}

void loop() {
  // sample-and-hold DC test signal
  //dc1.amplitude(random(0,100)/50.0 - 1.0);
  dc1.amplitude(-1.0/2.0);
  // print a counter so we know we're running
  Serial.println(count++);
  delay(100);
}
 
Last edited:
I am a fool. The issue was that I'd run out of AudioMemory. It didn't even occur to me that this could be possible, since I don't feel like I'm actually using very much, but I took a look at the TDM passthrough example and it's using AudioMemory(50) while I was using AudioMemory(20). Setting my AudioMemory to 50 solved the problem. I have input and output working now. Wow. Sweet.
 
The working code, for posterity:

C++:
#include <Wire.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <utility/imxrt_hw.h>

class AK4619 {
public:
  TwoWire* wire;
  uint8_t addr;
  void Init(uint8_t i2cAddress=0x10) {
    Wire.begin();
    addr = i2cAddress;
  }
  uint8_t writeReg(uint8_t deviceReg, uint8_t regVal) {
    Wire.beginTransmission(addr);
    Wire.write(deviceReg);
    Wire.write(regVal);
    return(Wire.endTransmission(true));
  }

  uint8_t readReg(int8_t deviceReg, uint8_t * regVal) {
    Wire.beginTransmission(addr);
    Wire.write(deviceReg);
    Wire.endTransmission(true);
    uint8_t numbytes = 0;
    numbytes = Wire.requestFrom(addr, (uint8_t)1, (uint8_t)false);
    if((bool)numbytes){
      Wire.readBytes(regVal, numbytes);
    }
    return(Wire.endTransmission(true)); //Send STOP
  }
};
 
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
//Serial.printf("SetI2SFreq(%d)\n",freq);
}

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=326,427
AudioOutputTDM           tdm2;           //xy=843,411
AudioSynthWaveform       waveform1;      //xy=347,179
AudioSynthWaveform       waveform2;      //xy=347,179
AudioSynthWaveform       waveform3;      //xy=347,179
AudioSynthWaveformDc     dc1;            //xy=575,252
AudioAmplifier           amp1;           //xy=540,355

AudioConnection          patchCord5(waveform1, 0, tdm2, 0);
//AudioConnection          patchCord6(waveform2, 0, tdm2, 2);
AudioConnection          patchCord7(waveform3, 0, tdm2, 4);
AudioConnection          patchCord8(waveform1, 0, tdm2, 6);

// -------------------------------------------------------
// UNCOMMENT ME TO CAUSE ISSUES WITH DAC1R and DAC2L!!!! -
// -------------------------------------------------------
AudioConnection          patchCord1(tdm1, 0, amp1, 0);
AudioConnection          patchCord2(amp1, 0, tdm2, 2);

AK4619 codec;

uint8_t regval = 0;
uint8_t error = 0;
int count = 0;

void setup() {

  Serial.begin(9600);

  Serial.println("hi");

  AudioMemory(50);

  //setI2SFreq(20000);

  Serial.println("begin");

  // AK4619VN startup sequence
  pinMode(41, OUTPUT);
  digitalWrite(41, LOW);
  delay(200);
  digitalWrite(41, HIGH);
  delay(200);
  codec.Init();
  delay(200);

  //if(codec.writeReg(0x00, 0b00110111)) Serial.println("Error."); // set last but repeated here for address consistency
  if(codec.writeReg(0x01, 0b11111110)) Serial.println("Error."); // set AK4619 regs
  if(codec.writeReg(0x02, 0b00011100)) Serial.println("Error.");
  if(codec.writeReg(0x03, 0b00000011)) Serial.println("Error.");
  if(codec.writeReg(0x04, 0b00100010)) Serial.println("Error.");
  if(codec.writeReg(0x05, 0b00100010)) Serial.println("Error.");
  if(codec.writeReg(0x06, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x07, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x08, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x09, 0b00110000)) Serial.println("Error.");
  if(codec.writeReg(0x0A, 0b00000000)) Serial.println("Error.");
  if(codec.writeReg(0x0B, 0b01010101)) Serial.println("Error.");
  //if(codec.writeReg(0x0C, 0b00000000)) Serial.println("Error."); //reserved
  if(codec.writeReg(0x0D, 0b00000000)) Serial.println("Error.");
  if(codec.writeReg(0x0E, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x0F, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x10, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x11, 0b00011000)) Serial.println("Error.");
  if(codec.writeReg(0x12, 0b00000100)) Serial.println("Error.");
  if(codec.writeReg(0x13, 0b00000101)) Serial.println("Error.");
  if(codec.writeReg(0x14, 0b00001010)) Serial.println("Error.");
  if(codec.writeReg(0x00, 0b00110111)) Serial.println("Error."); // turn AK4619 on

  // read back AK4619 register settings
  for(int i=0;i<=0x14;i++) {
    if(codec.readReg(i, &regval)) {
      Serial.println("READ ERROR!");
    }
    Serial.print(i, HEX);
    Serial.print(": \t");
    
    for (int8_t i = 7; i >= 0; i--) {
      uint8_t bit = (regval >> i) & 1;
      Serial.print(bit);
      if (i % 4 == 0)
        Serial.print(" ");
    }
    Serial.print("\t");
    Serial.print(regval, HEX);
    Serial.println();
  }
  Serial.println("Setup done");

  // set up waveforms
  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(30);
  waveform1.amplitude(1.0);

  waveform2.begin(WAVEFORM_SAWTOOTH);
  waveform2.frequency(30);
  waveform2.amplitude(1.0);

  waveform3.begin(WAVEFORM_TRIANGLE);
  waveform3.frequency(30);
  waveform3.amplitude(1.0);

  amp1.gain(1.0);
}

void loop() {
  // sample-and-hold DC test signal
  //dc1.amplitude(random(0,100)/50.0 - 1.0);
  dc1.amplitude(-1.0/2.0);
  // print a counter so we know we're running
  Serial.println(count++);
  delay(100);
}
 
Um ... yes. See post #2 :giggle:

Would I be right in thinking the only difference in the hardware settings resulting from your setI2SFreq() is the omission of
n1 = n1 / 2; //Double Speed for TDM
before CCM_CS1CDR is set? That could probably be put into an AK4619::enable() function along with all your setup register writes for a more typical audio hardware control class.
 
@john-mike - I just noticed you're using the odd-numbered TDM inputs. This tends not to work, as the slots are 32 bits wide and the original implementation shoehorns 16x 16-bit channels into 8x 32-bit slots. Paul had a plan to build an adaptor to shift the odd-numbered channels up to the even-numbered ones and send the result to a second codec (https://hackaday.io/project/176368-dual-interleaved-cs42448-chip), but that effort fizzled out about 3 years ago, and isn't helped by the CS42448 going obsolete.

TL;DR: if you use even channels and the code @eris has posted, you might have a result :)
 
I am a fool. The issue was that I'd run out of AudioMemory. It didn't even occur to me that this could be possible, since I don't feel like I'm actually using very much, but I took a look at the TDM passthrough example and it's using AudioMemory(50) while I was using AudioMemory(20). Setting my AudioMemory to 50 solved the problem. I have input and output working now. Wow. Sweet.
Sweet (y)
 
Um ... yes. See post #2 :giggle:

Would I be right in thinking the only difference in the hardware settings resulting from your setI2SFreq() is the omission of
n1 = n1 / 2; //Double Speed for TDM
before CCM_CS1CDR is set? That could probably be put into an AK4619::enable() function along with all your setup register writes for a more typical audio hardware control class.
Oh well now I just feel silly. Thank you lol.

Also, the setI2SFreq() function is now unnecessary. I had nabbed that from some other forum thread and was using it to slow things down a smidge so that the Pi Pico I was using as a logic analyzer could actually see the data reliably, but it works at full rate now so I'll probably just remove that code.

I do wonder if it might be possible to eventually get this running at 96kHz. I can't honestly say that I understand exactly what's happening in the setI2SFreq() function, but my eventual goal is use two of these AK4619 chips and try to get 32bit audio by creating a custom audio block that handles all the processing. 8i8o 32bit 96kHz audio would be phenomenal- I guess we'll see. c:
 
Hi Fellow AK4619 coders!

Great to find this post! Hopefully we can work together on this.

Last week I got a passthrough working on 24bit 192khz using a Teensy 4.1 TDM Audio setup by using an existing ESP32 codec AK4619 library which I modified to work with a Teensy and modified the AudioStream.cpp audio block for example to handle 32bit audio.
You can check out the code here, simply download it and put it in your library folder and run the passthrough example: Teensy4-4Chn-24bit-TDM-Audio

I am using an Eurorack module from apfelaudio.com which is equipped with an AK4619 which works now.
I also got a barebone version with an example of adding a sine wave to an input: https://github.com/Lytrix/Teensy4-i2s-TDM

Please let me know if this is also working for you or if you find any bugs/issues.

I am now working on playing a 24bit Wav file from SD card by modifying the existing Audio example, I can get something on my scope, but it is mostly noise :) I think it is due to how the release logic of a block is working which I don't 100% understand yet. Let me know if you have some experience on this.
 
Last edited:
Ok, I've managed to create an example recording a mono 32-bit wav file on channel 1 using the stripped down version which is not using the audio library: https://github.com/Lytrix/Teensy4-i2s-TDM
I initially tried to make the audio stream record queue example work, but I did not really grasp the bitwise operations and masking logic yet. I did got some output, but is was not signed for example.
 
I finally managed to get a proper passthrough up and running using AudioStream. I also got the Record RAW to SD example up and running using the Teensy Audio library by changing the audio_block data type to 32 bit. Yey!

In the end I modified the I2SQuad example and used some TDM simplifications to properly iterate over the 4 channels in each of the 128 samples.

 
Hi Lytrix,
I'm trying to get the library working with the pMod but can't.

trying your passthought example : When 2 channel are set, it works well. But as soon as is define 4 channels, it's doesn't work anymore ( tested on the non audio lib version) . And can't make it work on the audio lib version neither.

When i check the clock freq of the BCLK , it show twice what it should do
for example in 48khz, when mesuring with the pin 9:
MCLK=12288 kHz
BCLK=6144 kHz
LRCLK=48 kHz

Any clue before starting to go deeper in the code?
 
Last edited:
Hi Lytrix,
I'm trying to get the library working with the pMod but can't.

trying your passthought example : When 2 channel are set, it works well. But as soon as is define 4 channels, it's doesn't work anymore ( tested on the non audio lib version) . And can't make it work on the audio lib version neither.

When i check the clock freq of the BCLK , it show twice what it should do
for example in 48khz, when mesuring with the pin 9:
MCLK=12288 kHz
BCLK=6144 kHz
LRCLK=48 kHz

Any clue before starting to go deeper in the code?
Hi @tomatokotom, thanks for checkout the code! I also recall I did have some problems getting the 4 channels correctly setup on the 192khz in the beginning.

To have the same baseline: Did the passthrough example work without changing any code?
The example should run with 4 channels at 192khz as defined here: AudioConfig.h

I haven't tested the code running at 48 kHz, but you can try to test using another TDM setting by changing the row linked here or changing the raise/fall setting in the same function from false to true: control_AK4619VN.cpp to AK_TDM256_I2S_32B
You can also test using AK_512FS_8_48KS instead of AK_256FS_8_48KS as a clock rate.
 
I stopped following this thread and a lot has happened in a year!

@Lytrix I got your passthrough working after realizing both MCLK and BCLK go to teensy pin 21.
Any hints on porting audio objects over to use audiostream32? I tried to get the waveform working but it looks like you're not using pointers for audio blocks or something?
It's saying
Code:
cannot convert 'int32_t [128]' {aka 'long int [128]'} to
'int16_t*' {aka 'short int*'} in assignment
 bp = block->data;
 
The working code, for posterity:

This isn't working for me as is. Getting a chopped up output.
Capture.PNG

But if you add setI2SFreq(192000) it's nice and clean.
BUT it's not 192k, LRCLK shows approx 96kHz.
If you use setI2SFreq(96000) LRCLK is 48kHz and you've got a chopped up output again.
If you use setI2SFreq(384000)LRCLK is 192k and the output is close but with pops and clicks.

Either way thanks to everyone! It seems very close.
 
Hi @john-mike, The audio structure object needs to be using int_32t as a type field to be able to store and use 32bit of audio data. So you will need to update these structures from int_16t to int_32t where applicable if you see that error.

I've started working on an audio objects version, but still very much a wip, but maybe that will already work for you:

I stopped following this thread and a lot has happened in a year!

@Lytrix I got your passthrough working after realizing both MCLK and BCLK go to teensy pin 21.
Any hints on porting audio objects over to use audiostream32? I tried to get the waveform working but it looks like you're not using pointers for audio blocks or something?
It's saying
Code:
cannot convert 'int32_t [128]' {aka 'long int [128]'} to
'int16_t*' {aka 'short int*'} in assignment
 bp = block->data;
 
Hi @john-mike, The audio structure object needs to be using int_32t as a type field to be able to store and use 32bit of audio data. So you will need to update these structures from int_16t to int_32t where applicable if you see that error.

I've started working on an audio objects version, but still very much a wip, but maybe that will already work for you:
Yes that's the version I'm using. The issue is even after all the variables are changed to int32_t it's still trying to compare a single variable to a pointer. Did something change about how audio blocks work? Obviously I need to look at the your other code more, just wondering if you had already made progress porting over other objects. Thanks!
 
There will be no progress on my side for porting any other audio blocks in the short term. The current code is primarily a MVP to see if I could actually record, store and play 24 bit audio on a teensy, which it can, but it might be I accidentally broke the logic of using variables instead of pointers. I was not as knowledgeable on Cpp when I started the library. So there definitely might be issues you are describing where pointers and variables are not set correctly.

For now I am working on a midi sequencer/looper code that will be the foundation to play audio files in a later stage where I will integrate the library again.
 
Back
Top