Offline
Freiburg, Germany

Hey,

I've been trying to squeeze a decent arpeggio out of mgb via the nanoloop usb midi adapter using pitch bend messages and failed miserably, because the pitch bend steps are so low res that I can't even hit half-tones properly and everything is just ever so slightly detuned against each other.

Take a listen: http://wolkenspeicherplatz.de/sound/gb_test_2.mp3
This is the closest I was able to get near each note I wanted to hit in the arps.

After checking some things I found out that mgb apparently only interprets 5 bits of the high res signal, resulting in a total of 32 steps, when other hardware interprets at least 7 bits (ignoring the low byte) or even 14 bits (with the low byte interpreted). To make things worse, the frequency changes in a non-linear fashion, with exceedingly higher steps towards the top end.

Can anyone confirm that a real arduinoboy also produces only 32 frequency steps over the entire pitch bend range? Just want to rule out that the usb midi adapter is at fault for what ever reason.

Offline
Freiburg, Germany

I've been able to get closer to the semi tones this time, by reducing the pitch bend range from 12 to 6, transposing all arp notes 6 semi tones up and rewriting the intervals. to use the full range -100% to 100% instead of 0% to 100%

http://wolkenspeicherplatz.de/sound/gb_test_3.mp3

I'm happy with this now. Would still like to know the reason for this, if the low resolution pitch bend is just a part of mgb, if the usb midi adapter might be responsible or if it might even have been Renoise, which I tracked and automated all this in.

Offline

Thank you for making this thread, I was going to bring this up as well. I think it would be great to be able to set the pitch bend resolution higher within mGB, because when you are using higher pitch bend ranges, 32 steps is just not enough.

For arpeggios, the documentation states that if you send another note the same velocity as the previous note, it will not retrigger a note-on message, which allows for the arps you're looking for without any pitch bends required. In my experience, only PU2 consistently demonstrates this feature, and for PU1 you need to mess will the channel parameters a little bit (change pulse with, envelope, sustain on/off) and then the feature kicks in.

I remember somebody saying that the pitch-bend algorithm is particularly CPU intensive, as it calculates the frequency on-the-fly. This might be the reason the PB resolution is so low, so it doesn't affect speed of playback. Would it be possible to: instead of having the DMG calculate the frequencies every time there is a pitch bend into 32 steps, have a table of frequencies built into mGB, dividing each semitone into something like 32 steps? Then even with very high PB ranges (that maximum I believe is ±48) the mGB could start to interpret the finetune low-byte messages and have smooth, non-jumpy, tunable pitch bends.

Not to look a gift-horse in the mouth. mGB is great, however with the event of the NanoUSB being much more accessible than ArduinoBoys, an update would benefit a much larger group of people than in the past.

Offline
Freiburg, Germany
fluxer wrote:

For arpeggios, the documentation states that if you send another note the same velocity as the previous note, it will not retrigger a note-on message, which allows for the arps you're looking for without any pitch bends required.

I had considered doing it that way, or even via sustain, but I actually wanted my arps to stay flexible. Since I'm using a tracker for controlling mgb I would have to start using crazy high line per beat numbers in order to get an arp that's not an equal subdivision of the beat. In fact what you're hearing in my example is a bit humanized and not entirely clean. This also gives me the freedom to have arps slow down or speed up smoothly.

fluxer wrote:

In my experience, only PU2 consistently demonstrates this feature, and for PU1 you need to mess will the channel parameters a little bit (change pulse with, envelope, sustain on/off) and then the feature kicks in.

Yeah I've noticed the same. Couldn't figure out a sure-fire way to get it to work on pulse 1, so as long as I can't reliably reproduce it, I won't use it.

By the way, if anyone wants the xrns of this test tune to play with in Renoise, I've just made it available over there -> http://chipmusic.org/forums/post/147088/#p147088

Offline

To correct myself-- It's actually overlapping same-velocity notes that enable non-retrigger.

Offline
Los Angeles

Don't recall limiting it to 32 steps, if anything its 256 steps. The thing to remember though is the higher the pitch, the less steps you can have between notes because if I recall correctly the gameboy's freq for pu1/pu2 is 11 bits (2 registers, 8bit + 3bits).

A good example of this is looking at the lookup table for pitch frequencies used in mGB:

const UWORD freq[72] = {
  44,     156,  262,  363,  457,  547,  631,  710,  786,  854,  923,  986,
  1046, 1102, 1155, 1205, 1253, 1297, 1339, 1379, 1417, 1452, 1486, 1517,
  1546, 1575, 1602, 1627, 1650, 1673, 1694, 1714, 1732, 1750, 1767, 1783,
  1798, 1812, 1825, 1837, 1849, 1860, 1871, 1881, 1890, 1899, 1907, 1915,
  1923, 1930, 1936, 1943, 1949, 1954, 1959, 1964, 1969, 1974, 1978, 1982,
  1985, 1988, 1992, 1995, 1998, 2001, 2004, 2006, 2009, 2011, 2013, 2015
};

You can see that the higher the pitch, the less steps you can make between notes.

Offline
Los Angeles
fluxer wrote:

In my experience, only PU2 consistently demonstrates this feature, and for PU1 you need to mess will the channel parameters a little bit (change pulse with, envelope, sustain on/off) and then the feature kicks in.

Found the bug on PU1, it doesn't work if the Envelope is set to the 8th setting (the setting that is right before full sustain)
Weird, it may be a compiler issue. GBDK is really buggy- though that code is written in assembly.

*edit* mGB now to version 1.3.1 - Fixed this bug.

http://code.google.com/p/arduinoboy/

Last edited by Trash80 (Dec 20, 2012 12:49 am)

Offline

Thank you Trash80! I will most likely try it out tomorrow.

The 32-step pitch bend is apparent even on low to mid range notes. Is the NanoUSB at fault here then? Is it only sending mGB a 5-bit pitchbend signal?

Can anyone with an Arduinoboy confirm that mGB will interpret higher-res pitch-bend messages sent from one?

Offline
Los Angeles
fluxer wrote:

Thank you Trash80! I will most likely try it out tomorrow.

The 32-step pitch bend is apparent even on low to mid range notes. Is the NanoUSB at fault here then? Is it only sending mGB a 5-bit pitchbend signal?

Can anyone with an Arduinoboy confirm that mGB will interpret higher-res pitch-bend messages sent from one?

It may well be 32 steps at the fault of my math. (I do some shifting for precession since there are no floats) It's tricky to get the little guy working properly with as few instructions as possible. Maybe I'll rewrite it at a later time to use some sort of scaled lookup or something else.

Offline

What is your current math, out of curiosity?

Offline

Well I did some math of my own, and generated a frequency look-up table using MaxMSP, dividing each semitone into 128 parts.

https://www.dropbox.com/s/bgcok8265ixpe … -table.txt

There are 9216 values total. The first value is the lowest C, and every 128th value after that is the equivalent of a non-pitch-bended note one semitone higher than the previous. (the 129th value is C#, 257th value is D, etc).

Not pressuring you Trash80 or anything, I just thought maybe I could help out a bit smile

Offline
Freiburg, Germany

it would be good if somebody could confirm that this also happens with an arduinoboy and is not a problem specific to the nanoloop usb dongle

Offline
Los Angeles
fluxer wrote:

What is your current math, out of curiosity?

The shifting is to give some precision to avoid floating point math...

if(pbWheelIn[synth] & 0x80) {
    currentFreq = freq[noteStatus[synth_pitch]] + (((freq[pbNoteRange[synth_note_range+1]] - freq[noteStatus[synth_pitch]]) * (((pbWheelIn[synth] - 0x79)<<7) / 0x80))>>7);
} else {
    currentFreq = freq[noteStatus[synth_pitch]] - (((freq[noteStatus[synth_pitch]] - freq[pbNoteRange[synth_note_range]]) * (((0x80 - pbWheelIn[synth])<<7) / 0x80))>>7);
}

I changed it to +-7 bit precision. Check it out now: (v1.3.2)
http://code.google.com/p/arduinoboy/

And I'll optimize this later and rewrite it in asm. Don't have time lately.

Offline
Freiburg, Germany

Thank you for the new version trash80. I've put it through its paces and the pitch bend is really a lot smoother.

Your math seems to be off though, I'm testing with pitch bend range 0C and experiencing weirdness starting at notes below C-5: The pitch bend starts wrapping around at negative pitch bend values. At first only towards the end close to -100%, but the lower the note gets the earlier it happens, and finally at notes below B-3 things are starting to go random, with a random pitch jump for any value in negative pitch bend land. That's also the point where the positive pitch bend starts wrapping around like the negative did for notes below C-5.

I've recorded two simple examples to test the smoothness, when I noticed it happening to me. I'm playing a C-5 on PU2 and a C-4 on PU1 with a PB range of 0C being one octave up and down.
For the C-4 it wraps around at -50%, the next lower value jumping the pitch back to its original pitch. Take a listen. First mgb 1.3.2 and afterwards mgb 1.3.0 for smoothness comparison. Notice that the wraparound doesn't happen in 1.3.0

http://wolkenspeicherplatz.de/sound/mgb … arison.mp3

this is my automation curve for both channels

Offline
Los Angeles

It's not the math, you are hitting the lowest note possible and it's wrapping. I could put in a if condition to avoid the wrapping, but that adds overhead. Every instruction counts to keep up with MIDI data on a DMG.

Offline
Los Angeles

Oh wait I see... let me look.