[WIP] 4 channel Music

I found that issue too and opened a PR with a fix a few hours ago see https://github.com/TEAMarg/ATMlib/pull/6 and https://github.com/TEAMarg/ATMlib/issues/5

1 Like

Hi, I made sure I was compiling with my version when testing. I just cloned your repo (thanks for setting it up) and tested both versions of the “sketch” and they sound the same on my Arduboy. I initially thought you were experiencing the high pitch noise instead of music but now I understand that you get a high pitch noise and music. That’s interesting, maybe it has something to do with my code using a lower timer frequency. The problem is that I cannot reproduce the issue on my Arduboy!

1 Like

hi @dxb Could you hear it in the video?

Hi @JayGarcia, I could not hear it in the video but I believe it’s because of my laptop (rather than being deaf to those frequencies). I have a potential explanation for what you are experiencing and I’d like you to try the following workaround. Please change these lines in your local copy and let me know if the issue goes away.

diff --git a/src/ATMlib.cpp b/src/ATMlib.cpp
index 8582921..ac459e6 100644
--- a/src/ATMlib.cpp
+++ b/src/ATMlib.cpp
@@ -119,7 +119,8 @@ void ATMsynth::play(const byte *song) {
   channel[3].freq = 0x0001; // xFX

   TCCR4A = 0b01000010;    // Set both OC4A and #OC4A pins
-  TCCR4B = 0b10000010;    // Frequency correct PWM (dual slope), clk/2/OCR4C ~= 31250Hz
+  TCCR4B = 0b10000001;    // Frequency correct PWM (dual slope), clk/OCR4C ~= 31250Hz
+  TC4H   = 0x01;          // Set bit 8 of the 10bit counter to preserve the expected rate
   OCR4C  = 0xFF;          // Resolution to 8-bit (TOP=0xFF)
   OCR4A  = 0x80;
   TIMSK4 = 0b00000100;    // Enable overflow interrupt

Thanks. Not being able to hear the tone due to limitation in hearing is somewhat of a sensitive subject and I didn’t want to come off like a jerk. As I understand it, there are many factors as to why such a high pitch could not be received by ones ears – and now I recognize that reference speakers as a limitation in reproducing the sound.

Thank you for picking up on my message. =)

I’ve compiled the sketch w/ the edits and can reproduce the high-pitch noise.

  osc[3].freq = 0x0001; // Seed LFSR
  channel[3].freq = 0x0001; // xFX

  TCCR4A = 0b01000010;    // Fast-PWM 8-bit
  TCCR4B = 0b10000001;    // Frequency correct PWM (dual slope), clk/OCR4C ~= 31250Hz
  TC4H   = 0x01;
  OCR4C  = 0xFF;          // Resolution to 8-bit (TOP=0xFF)
  OCR4A  = 0x80;
  TIMSK4 = 0b00000100;

  // Load a melody stream and start grinding samples
  // Read track count
  trackCount = pgm_read_byte(song++);

— Update. I’ve tried with another Arduboy and can produce the problem there too. :frowning:

Oh well, back to the drawing board it is… Thank you for trying it out!

1 Like

Anytime. Ping me if you have any ideas/etc… I know little about the hardware to the degree that you do and will be happy to test out code/etc.

I’ll look around my office to see if we have Arduboys from a different batch of manufacturing to reproduce. This may take some time though. =)

Thank you for the offer. I’ll post again after checking waveforms/spectrum (may take a while) and get back to you with an update. A shame this didn’t work immediately, I wanted to go on and make more changes to the interrupt handler but I guess it will have to wait :man_shrugging:

Thanks. :slight_smile:

In your testing, have you noticed that it takes ~250 frames to start a song?
This example does a print every frame and i found it to be an interesting trait of the player :slight_smile:

Yes I noticed but haven’t investigated the reason… and while I was writing this I realised what causes it. cia_count is uninitialised but probably 0 so you have to wait for it to count down to 0 before the play routine gets called for the first time. https://github.com/TEAMarg/ATMlib/blob/2a410b1e8013d5c69a10079bb7016a91e00d8836/src/ATMlib.h#L60

I have tested a fix and will push it later today to my fork.

Fix for delayed song start is here.https://github.com/dxxb/ATMlib/commit/14f44cd81845c60a0c98fabd87635121b8981d09

I confirmed the high pitch (~15kHz) noise you mentioned (and also confirmed my hearing is not as good as it used to be). There is something interesting going on here: the noise appears when the interrupt rate (timer overflows rate) is lowered. Using dual slope PWM mode I can halve the interrupt rate without affecting the frequency of the PWM signal but the noise still appears. I may have to back out my changes and do something else to reduce the number of cycles used by the synth.

1 Like

DUDE!! You are ON FIRE!!!

I wish i could understand what’s going on and debug these issues.

Thank you so much!!

1 Like

:rofl: glad it was helpful. FYI if I can solve the high pitch noise issue at lower interrupt rate I have plans for ATMlib (MWHAHA :japanese_ogre:) Looking at the assembler code I figured we could have 3 (small)wavetable based channels instead of 3 fixed waveform channels. Fixed waveform channels would still be used by default.


I’m currently looking at the code to see if there is a way to inject sfx capabilities. PlayTunes had PlayTone which would mute a channel in lieu of another high priority tone.

My thoughts are:
Ch1 (Square), Ch3(Triangle), Ch4 (Noise) are used for music while Ch2 (Square) could be used exclusively for SFX.

Thoughts on this approach?

----- EDIT ----

I found JO3RI’s response to me a while back:

  if (arduboy.justPressed(A_BUTTON)) {
    for (int n = 500; n < 4000; n += 10) {
      osc[0].vol = 63;
      osc[0].freq = n;
      osc[0].vol = 0;


Muting, updating the osc and unmuting works for simple effects. I’d want the sound effect to be expressed as tracks you can ‘call’ (e.g. call_track(ch_num, track_num); ), this would behave similarly to the call tracker command but would be triggered from outside the play routine. When the sfx track finishes it returns and playback resumed from the point in the song where the ‘call’ was injected.

That would be the ideal path and inline with how Playtune and Tones work in addition to many retro consoles.

@dxb @JayGarcia thank you so much both of you for committing to the lib, giving ideas and testing stuff.

BUT, I’m still not capable of working on the ATMlib, because I’ll stay hospitalized till the end of the year …

I just wanted you both to know, I noticed all your hard work and I’m sorry I can’t jump in right now.



Hi @JO3RI, not a problem bro. No need to be sorry – we need focus on what’s important and get healthy!!

@dxb and I are “heads down” on some of these ideas in a fork and once we’ve gotten to a point where we are ready to share. We think that these updates will be a huge win for the lib and the Arudboy community.

More to come. Rest well bro.

1 Like

Hey @JO3RI, no worries. Changes to ATMlib are being published on a fork for the time being and we can review them when you get back. Good luck and get well soon!


How can people try out ATMlib2 features and effects so they fall in love with it like we did? Ladies and Gentleman, I give you the MIDIBoy [1]

MIDIBoy.m4v (536.7 KB)

This is a very very basic proof of concept. It sets up arpeggio effect and just does note on/note off on the first 4 MIDI channels (mapped to ATMlib’s channels [0,3]). The library is not ready for release but we are getting close.

[1] AKA: how do we create hype? A teaser!

1 Like