ArduboyTones FX

ArduboyRecording(5)

I have hacked a copy of @MLXXXp’s ArduboyTones to work with the FX chip. You can now stream music and graphics from the FX chip simultaneously. I have included a sample program that shows how and includes streaming from the FX and from Ram as a comparison.

It can be found here.

The approach is slightly different to the other tones() functions as it uses a circular buffer to hold the data to play. The buffer is replenished as part of the standard loop() processing, as shown below. This is primarily due to the fact that the FX and ArduboyTones would fight over interrupts.

The buffer size is configurable but my testing has shown that even the smallest buffer of 4 - 6 unit16_ts is enough. I guess if you have some really, really fast music and a really, really slow frame rate you could up it to a lavish length of 16!

#include <Arduboy2.h>
#include "src/ArduboyTonesFX.h"
#include <ArduboyFX.h>
#include "fxdata/fxdata.h"

Arduboy2 arduboy;
uint16_t buffer[8]; 
ArduboyTonesFX sound(arduboy.audio.enabled, buffer);

void loop() {

  if (!arduboy.nextFrame()) return; 
  arduboy.pollButtons();
  sound.fillBufferFromFX();

  ...

  sound.tonesFromFX(KickOutTheJams);
4 Likes

This is awesome news, more and more tools to use the FX capabilites!

These little distractions are preventing from creating my next game.

ArduboyPlaytunes next!

Nice! How many royalty free songs can we cram in one game system? :smiley:

Royalty free? Muzak??

I don’t have time to look at the internals, but I will point out that if you also add this constructor:

template<size_t size>
ArduboyTones(boolean (*enabled)(), uint16_t (&buffer)[size]) :
	ArduboyTones(enabled, buffer, size)
{
	static_assert(size < 256, "Buffer too large");
}

People can just do ArduboyTones sound { arduboy.audio.enabled, buffer }; and then not have to worry about providing the size manually.


Oddly enough, royalty-free music tends to be more electronic techno-beat/synth stuff.

It might not be Nintendo-tier, but some of it is better than Minecraft’s music (though that’s not saying much).

(‘Muzak’ is another one of those pesky genericised trademarks by the way.)

Because no one would pay for that crap?

After speaking with @mlxxxp, I might maintain this library in parallel to the official ArduboyTones library. I was thinking what I started with would be heavily altered to incorporate into the official library in a way that doesn’t add additional memory requirements or break anything.

Thus, these sorts of improvements are more than welcome.

1 Like

I’d agree, but I feel like I might be deeply offending someone somewhere. (Probably someone who lives in a very urban area and likes to go clubbing. Or Markus Persson.)

If you’re going to do that, perhaps it would be better to name it ArduboyTonesFX, ditch the conditional compilation and only retain the FX-relevant functionality?

After all, I doubt many people are likely to be storing their sounds both in progmem and on the FX.

That’s about all I have to offer at the moment, and I only really mention it because it’s a bit of a no-brainer (zero cost + ease of use + extra safety), but if I get chance to look in more detail and spot anything useful I’ll let you know.

Yes definitely a name change is in order so as not to confuse people (and the compiler).

That’s an interesting question. Its possible that you might want a theme to be playing from the FX but have small beeps and tones in memory or be generated randomly.

Please do.

1 Like

I would have thought BeepPin1/BeepPin2 would suffice for the former at least.

I suppose the real litmus tests would be:

  • How often is anyone likely to mix (complex) progmem and FX sounds?
  • If you dropped progmem support, could you reduce the memory footprint?

You could possibly do this from your proposed ArduboyPlaytunesFX library.

1 Like

I have updated the sample program to show streaming music and graphics from the FX card simultaneously.

New repo GitHub - filmote/ArduboyTonesFX

You can use this library in your FX Game Jam entry :slight_smile:   

@MLXXXp is it possible to bring out the ‘frequency’ rather than the actual tone name when using the midi2Tones programme? This program works fine when using ArduboyTones but not so when you are looking to embed the results in a FX file.

I did the following tests and was unable to produce a result automatically from the programe that was suitable. Not sure if it is possible or I am doing something wrong …

Using the midi2Tones conversion normally (using the -o2 flag), I get:

const uint16_t Triumph[] PROGMEM = {
  NOTE_B5,136, NOTE_C6,136, NOTE_B5,136, NOTE_AS5,136, NOTE_B5,136, 
  NOTE_REST,136, NOTE_E6,818, TONES_END
};

According to ArduboyTonesPitches.h, the NOTE_B5 is equivalent to 998 and C6 is equivalent to 1047. I can then subsititue the values by hand and get the following which plays correctly in ArduboyTones and ArduboyTonesFX.

const uint16_t Triumph[] PROGMEM = {
  988,136, 1047,136, 988,136, 932,136, 988,136, 0,136, 1319,818, 32768
};

I then played with the -f parameter on the existing ``midi2Tones.

With -fa, I get:

const uint16_t score[] PROGMEM = {
 494,136, 523,136, 494,136, 466,136, 494,136, 0,136, 659,818,
 TONES_END
};

With -fb, I the same with only the TONES_END value swapped to the euqivalent 0x8000

const uint16_t score[] PROGMEM = {
 494,136, 523,136, 494,136, 466,136, 494,136, 0,136, 659,818,
 0x8000
};

Just realised the generated numbers are half of the expected frequencies. Not sure if that is expected or not.

Actually, the numeric note frequencies output using the -f parameters are correct. The note names generated when a -f parameter isn’t included are one octave higher than they should be :frowning_face:

When I wrote the code for generating note names, I must have overlooked the fact that MIDI note numbers start one octave below C0. You could consider them to be in octave minus 1. However, these frequencies (MIDI notes 0-11) aren’t supported by ArduboyTones, so I’ve changed
midi2tones to output “0” or “0+TONE_HIGH_VOLUME” for them (the same as what parameter -fa would do).

I’ll release a new version of midi2tones shortly, with this fix.

Unfortunately, this means MIDI input files will have to be (properly) transposed one octave higher, then reprocessed with the new midi2tones, if you want to generate the proper note names to match the frequencies of the MIDI note numbers.

3 Likes

I didn’t realise it was an octave out. I use admit o have moved music up and down the scale previously until it sounded right on the little Arduboy speaker.

The current release, V1.0.0, of midi2tones definitely has a bug that note names output using -o2 are an octave higher than frequencies output when -fx is added (with the -fx output being correct). That’s according to all the MIDI note number frequency references I’ve found, such as this one.

However, I’ve tried a number of sequencers and found that some read and write a different octave in a MIDI file than what’s shown in the sequencer. You may have to set the base octave for MIDI files in the preferences for the sequencer you’re using.

If you don’t want to change the pitches in the MIDI file, you can use the midi2tones -k parameter to move them up or down.

A semitone higher?

1 Like

No, 12 semitones higher. (To avoid confusion for those who don’t follow your link and watch it.) :grin: