Friday, April 17, 2015

Getting Real Pt Addendum - Are my ears broken?

A bunch of folks have asked what's going on in the tuning with this transcription? To be honest, it's difficult. Neither musician tuned their sampled instruments to a standard tuning, and dealt with the situation on their end by simply transposing certain instruments up and down to compensate. I can't quite remember if Scream Tracker let you tune anyways (but Impulse Tracker did). So lots of their instruments are just a hair out of tune with respect to each other.

The problem of course is that I'm remapping the music to a VSTi that has a common tuning. I think I did pretty well for most of the remapping, but some people have noted that some of the movements in the piece are out of tune with respect to other movements, while in the original this isn't the case.

The truth is? Laziness on my part, plus a desire to minimize the number of note-instrument combinations and lower entropy...even if the movement was a bit out of tune to the entire song.

But there was one area I really made a mistake, in the blue flowy sea landscape about 7:30 into the production, I b0rk3d up the melody. The lead that PM was using was simply tuned off from the rest of the tracks, and when I tried to fix it and transpose it, I ended up putting it a perfect fifth off of what it should have been. (greets to yzi on Pouet for catching the exact nature of the problem). Lots of people caught this issue, but lots of people didn't. I'm definitely one of those that didn't...I attributed the "off sound" to different instruments, no portamento, etc. instead of me simply being out of tune.

To prove it, I walked myself back through the original score, retuned the lead to match, and simply transposed the lead till it sounded like the original and sure enough, it was a fifth off!

So if you want a version with that lead fixed. Here it is.

I probably won't spend the time to fix the rest of the minor issues and transposition problems. To be honest, I'm ready to move on to different music, having heard some version of this soundtrack too many times to count!


Table of contents


4. Origins
5. Entropy

Sunday, April 12, 2015

Getting Real Pt 17. - Options

At last, after weeks of work, we almost had a full production, and it was fitting inside of 8k. Seven was still hard at work (and would be up until the submission deadline). It occurred to him that we might actually now be under our byte budget. He wondered if there were things I could reintroduce to the song that I had previously cut. At the same time, Coplan noted that some of the leads were a little weak and getting lost in the mix. I decided to give Seven some options.

Per the Clinkster docs:
"You can use the Delay effect (under Track DSPs) with these restrictions:
- The "L Feedb.", "R Feedb." and "Send" sliders must be at the same position.
- "Mute Src." must be off.
- No L/R Output Pan.
- If you use the Delay effect on multiple tracks, you must use the exact same
  parameters on each track."

I had cut almost all of the hand-made digital delays in the song (see Part 9) saving considerable space. But I figured, instead of adding them back in, why not use the Delay Effect instead and make this thing fully a product of modernity?

Like most things, anywhere the Clinkster docs say "you can" means you're going to use bytes doing it. It's also very limited, any track with a delay has to have exactly the same delay parameters, so I had to choose options that sounded reasonable on all the tracks I wanted to add delay to.



This added a mere 22 bytes, far fewer than adding the original hand-coded delays. This became Cut Iteration #7. I also added back some of the instrument doubling I used to bring the leads out in the mix. This was Cut Iteration #8, and because each new octave/instrument was another set of note-instrument-velocity-length combinations just a few notes added back 159 bytes. So by Cut #8, we were almost back to where we were with Cut #5, but hopefully with better sound.

Seven in the meanwhile was still experimenting with mono-vs-stereo playback. Using mono shaved a few bytes from the production as it turns out, but required more mutations to Clinkster.

I listened to Cuts #6, 7 and 8 in mono to see if they sounded reasonable, and though I wasn't thrilled with it, they sounded "ok" over loud speakers. I decided to give Seven the final call at the party place and gave him a choice of cuts and mono or stereo as he needed. At this point there really wasn't any more I could cut without making the song start to sound completely unrecognizable. I'm actually not sure which one Seven finally went with, but I was glad to be able to give him some choices so he could focus on coding.

Here's how it played at the party:



I couldn't attend the party in person, so hearing the crowd enjoy the song was awesome. I loved hearing people shout out and fill in the missing vocal bits, singing along with it and other mayhem. Most important for a competition, we did pretty well. We came in a close 2nd in a very competitive year. The post-party reaction was more mixed, I'm not sure that the modern scene crowd quite understands the technical limitations and the amount of effort that goes into fitting something interesting into 8k. After talking with a couple people, some even were confused that it looked so terrible for such a high resolution as 7680×4320. After correcting them that this wasn't a resolution category but a size category, the light seemed to finally click on.

Stranger to me are people who seemed angry about this production. I've never really seen or heard of people get angry at a demoscene production before, so we must have pushed a button somewhere. But it doesn't really weigh on me too much. Comments surrounding the absolutely amazing Commodore 64 remix are also quite mixed, even though it won its competition.

With productions like this, there's inevitably compromises, some are easy to make, some are hard. And of course this is a hugely compromised production. However, the entire production fits into less space than some of the intermediary images in the original! It's my hope that this series has helped provide some insight into what some of those compromises were, why they were made, and how they shaped the final production.


(Since you've read this far, here's all the cuts and troubleshooting mixes from this series).


Getting Real Pt 16. - Full Contact Knife Limbo

Last time I talked about how I cut echos and simplified the hell out of the complex rhythm parts in the score. Guessing Seven might need more space, I decided to keep going. There were still some things that I guess I could cut without being too noticeable. I think the results were mixed, but it did pay off.

For example, I had noticed that the Kettledrum part generally mirrored a couple other parts in the score. And the instrument I had created for the Kettledrum, sounded a bit like another instrument I had. So I went through and either cut or merged the entire part, or reassigned it's part to another instrument played at a lower octave.

I also went through and tried to standardize as many of the velocity/volumes as I could. I decided that in general, I'd allow two volumes, the default, and 30. There were some concessions I made for artistic reasons. If I felt an echo or a crescendo was particularly important I'd allow other volumes. But the idea was that a listener might not really notice a difference between a crescendo slowly moving up individual volume values, and one that just used 10, 15, 20, 30, 40, 50 and 60. But this might take a crescendo from 32 different note-velocity/volume combinations to just seven.

I also eliminated extra channels where I could. For example, in Skaven's original introduction, he used three channels for the hi-strings. I cut one out figuring that two notes would build up enough of a chord to sound okay. This killed off a few of Clinkster's "virtual" channels, shaving more bytes.

I also simply eliminated notes. For example, there's this wonderful cycle that Purple Motion starts his section with.

Bass
00 C#3 01 ..
01 ... .. ..
02 C#3 01 ..
03 ... .. ..
04 C#2 01 ..
05 ... .. ..
...
...
...
60 B-2 01 ..
61 OFF .. ..
62 B-1 01 ..
63 OFF .. ..

I know that musically, the B-2 and B-1 at the end of the pattern (positions 60-63) is just a lead-in into the next go around to the notes at positions 00-04. They're less musically important than the C#s. So I simply cut them out.

 Another example from the Purple Motion section.

Solobrass
00 C#3 05 ..
01 ... .. ..
02 C#3 05 ..
03 ... .. ..
04 C#4 05 ..
05 ... .. ..
06 C#3 05 ..
07 ... .. ..
08 C#3 06 ..
09 ... .. ..
10 C#4 06 ..
11 ... .. ..
12 C#3 05 ..
13 ... .. ..
14 C#5 05 ..
15 ... .. ..

Was turned into this.
Solobrass
00 C#3 05 ..
01 ... .. ..
02 OFF .. ..
03 ... .. ..
04 C#4 05 ..
05 ... .. ..
06 OFF .. ..
07 ... .. ..
08 C#3 05 ..
09 ... .. ..
10 C#4 05 ..
11 ... .. ..
12 OFF .. ..
13 ... .. ..
14 ... .. ..
15 ... .. ..

I did this kind of note shaving everywhere I could. And finally got it down to Cut Iteration 6, the smallest the song would get and 3,653 bytes from where I started at 4,345 bytes. That's right the first 9 minutes of the Second Reality soundtrack in just hair over 4k.






At this point, Seven was still hacking away at Crinkler/Clinkster (we were attacking the problem from both ends) and building new versions of the production. We were getting really close and he was working non-stop.


Getting Real Pt 15. - Pressure Cooker

We lost about 3 days figuring out the broken music, and the competition was starting to draw near. The pressure was turning way up. Seven was still building out sections and my music wasn't getting smaller. We had reached Cut Iteration 4 and based on the minimal gains I made there I was ready to declare that no more music could be cut.



But Seven kept sending status updates with the full production hovering in the 9k area. This wasn't good. We started talking about crazy things, like how Clinkster creates and counts virtual instruments that aren't really there and if I could eliminate any of them, or maybe Seven could start hacking at Clinkster itself, or putting the song in mono instead of stereo to shave a few dozen bytes.

This didn't sound good, and I figured that Seven was already squeezing the hell out of his code. So I started brainstorming some ideas on how I could possibly cut more. I wasn't hopeful.

Then it struck me -- entropy! Both composers, and especially Purple Motion had used all kinds of effects to give his sound space (see Part 9 of this series). Furthermore, he had several different drum rhythms and fills throughout his sections, but the whole production was at the same tempo. I had spent so much time cutting into the synths, with just a couple exceptions, I had simply ignored the percussion.

So, in almost a fevered dream, I started "flattening" the sound, cutting out echos where I judged they were minimally needed and building up a very simple (and predictable and therefore low entropy), but general purpose drum rhythm I could use for most of the parts that called for drums. I also tried to engineer in a few layers I could simply mix and match.

I discovered the following basic drum routines in Purple Motions music (after converting them over to Renoise and Clinkster):

Somewhat simplified here:
  • read left to right
  • || means note-off
  • lower-case notes mean lower-velocity/volume
  • assume missing instrument sections are blank
#1
HiHat .. .. .. .. .. .. .. .. E5 .. || .. .. .. .. .. .. .. .. .. .. .. ..
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#2
BD    C3 .. || .. .. .. .. .. C3 .. || .. .. .. .. .. C3 .. || .. .. .. ..
Snare C5 || .. .. .. .. .. .. C5 || .. .. .. .. C5 || .. .. .. .. .. .. ..
HiHat E5 || e5 || e5 || e5 || E5 || e5 || e5 || E5 || e5 || e5 || e5 || e5
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#3
BD    C3 .. .. .. .. .. C3 .. || .. .. .. .. .. .. .. C3 .. || .. .. .. ..
Snare C5 || .. .. .. .. .. .. C5 || .. .. c5 .. C5 || .. .. C5 .. .. .. c5
HiHat E5 || e5 || e5 || e5 || E5 || e5 || e5 || E5 || e5 || e5 || e5 || e5
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#4
BD    C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. ..
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#5
BD    C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. ..
Snare .. .. .. .. .. .. .. .. C5 .. || .. .. .. .. .. .. .. .. .. .. .. ..
HiHat || .. .. .. E5 .. .. .. || .. .. .. E5 .. .. .. || .. .. .. E5 .. ..
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#6
BD    C3 .. .. .. C3 .. .. .. .. .. .. .. C3 .. .. .. C3 .. .. .. .. .. ..
Snare .. .. .. .. .. .. .. .. C6 .. || .. .. .. C6 .. || .. C6 .. || .. ..
HiHat E5 || .. .. E5 || .. .. E5 .. .. .. E5 || E5 || E5 || .. .. E5 .. ..
Blipp .. .. .. .. .. .. .. .. .. .. .. .. a5 .. || .. .. .. .. .. .. .. ..
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#7
BD    C3 .. .. .. C3 .. .. .. .. .. .. .. C3 .. .. .. C3 .. .. .. .. .. ..
Snare .. .. .. .. .. .. .. .. C6 .. || .. .. .. .. .. .. .. .. .. .. .. ..
HiHat E5 || .. .. E5 || .. .. E5 .. .. .. E5 || E5 || E5 || .. .. E5 .. ..
Blipp .. .. .. .. .. .. .. .. .. .. .. .. a5 .. || .. .. .. .. .. .. .. ..
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#8
BD    C3 .. .. .. c3 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
HiHat .. .. .. .. .. .. .. .. E5 || e5 || e5 || e5 || E5 || e5 || e5 || e5
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

#9
BD    C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. ..
HiHat E5 || e5 || e5 || e5 || E5 || e5 || e5 || e5 || E5 || e5 || e5 || e5
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

And a half-dozen more. Plus an incomprehensible number of drum fills and minor variations. I realized that I could greatly simplify things if got rid of most of these. 

Since I was doing this to cut space, I figured I should go all the way. The general rhythm I needed to replace these with had to be low-entropy, but also mildly interesting to listen to.

I decided to use a very basic house rhythm.

BD    C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. .. .. C3 .. .. .. .. .. ..
Snare .. .. .. .. .. .. .. .. C5 || .. .. .. .. C5 || .. .. .. .. .. .. ..
HiHat E5 || .. .. E5 || .. .. E5 || .. .. E5 || .. .. E5 || .. .. E5 || ..
      00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22...

I didn't replace all of the rhythms above with this basic rhythm. But I did replace most of them. For the ones with the "Blipp" instrument, I kept that one in, simply layering it over the above.

I figured that one of the reasons Purple Motion had so many different rhythms was simply to keep the music interesting. So I also wrote a version that had a slightly more complex hi-hat part.

I also combined #9 above with a variation on a more complex bass drum part that I used in a couple places. 

The effect of all this was cut iteration #5, or an 887 byte drop! All told, I had cut 3,400 bytes from my initial version or more than 3k!

Getting Real Pt 14. - In Case of Emergency, Break Things

While going through this, I'd send Seven near daily updates of the .xrns file for him to compile into the production. Based on that and him running it under heavy compression, we'd get a near daily snapshot of how we were doing size-wise. Things were going smoothly for the most part, but we were still way too big. It seemed like every day I'd get a "we just dropped to 9.3k!" from Seven, followed by a "okay, we're back up to 10k when I added another section". Coplan, ever busy with real-life chimed in encouragement, ideas and kept moral boosted with jokes about in-laws and taxes and such.

I'm not exactly sure what Seven's process looked like during all this, but I imagine it was something like this:


Except with more plasmas and scrollers, and my reorchestrated Second Reality score.



Somewhere around iteration #3, Seven sent me an email, "Ahum, I notice once I actually try to play the music it sounds completely random, like one pattern from somewhere at the end plays first, and the some random notes with a lot of silence. The easy_exe gives me the same result, although the cr4.xrns plays fine in renoise. Can you confirm the music.exe that is generated by easy_exe sounds correctly at your end?"

I checked, and sure enough, the music sounded like a random note explosion. Like a John Cage piece for prepared piano, except using Clinkster sounds.


This was not good.

I confirmed the problem and started trying to troubleshoot the problem. I assumed it was some issue that Renoise had introduced during transcription. Maybe some errant hidden data that was breaking everything. It was my fault, I had simply been cutting and listening to the result in Renoise, but what I should have been doing is putting the song through the entire 4-step toolchain. If Seven hadn't been trying to build the entire production everyday to verify, we wouldn't known until it was much too late.

I stepped back through previous iterations until I found one that didn't break. Then I took the next iteration and cut all the patterns out except for the first one. Saved it and then put it through the tool-chain. It sounded fine.

So I did the same thing and kept the first two sequences and test. Fine again. I kept repeating until somewhere around sequence 69 or 70, it broke. And this is why Seven makes the big bucks. Using this information and the 70 or so version I had created up to that point (I actually ended up with a little over 100 different test versions trying to solve this problem) Seven pinpointed the problem to an issue in the Clinkster tool-chain, not Renoise!

It turns out that I had an instrument that had more than 127 note-volume-length combinations and had simply introduced so much entropy into the song that it broke during the Compile/Compress stages (Ed. Seven wishes I'd explain it this way "It turns out that I had an instrument that had more than 127 note-volume-length combinations, which is (although the documentation doesn't mention it) the maximum Clinkster supports."). Apparently, nobody had ever pushed the tool this far, we were literally pushing beyond what the tools were capable of at this point.

Seven narrowed down the issue even more, edited the asm code and sent me an updated clinkster.asm file and the problem was solved! If anybody saw this production during the compo, you might have noticed the "mutant Clinkster" during the introduction of the production. Now you know where that all came from.


Getting Real Pt 13. - Cutting Yourself

7,998 bytes, terrifyingly big, at least if you're considering the music for an 8k demoscene intro. Suddenly Seven and I were sending almost daily emails back and forth, was it still possible? Could we still pull this off? Nevermind that the soundtrack was smaller than it had ever been before, it was twice as large as it needed to be. What were we going to do?!

I let it set for a day, thinking it over, thinking like a coder, letting my rational brain take over and analyze the situation. Maybe I could shave 2-3k off, get Seven some much needed breathing room. Maybe we could simply cut parts. People would understand wouldn't they? Compromises have to be made in this kind of production. I'm sure the tech savvy demoscene audience would get what we had attempted. So I decided to see where I could get doing some smart cuts.

I didn't keep a good change log, I just saved after every session as I went along. And it started to work! With each cut iteration, I removed instrument pairings (saving note data), simplified the volumes/velocties (reducing entropy by getting rid of note-velocity pairs) and even merging instruments (further removing entropy). I also got rid of those extra patterns I didn't need.

By the 4th iteration I was pretty sure I had cut just about everything that was possible and I had cut a whopping 2,513 bytes!


With going over each track and each instrument over and over again to make cuts (and 105 patterns of this), it took about 4 days to get from iteration #1 to iteration #4. Or an average of 628.25 bytes per day. Each day bought back almost 8% of the size of the total production. It was hard, exacting work, but it was getting us in range.

Very important, even before we got to the first final score iteration, Seven started linking the music in with the visuals and asking me to verify if they sounded correct. This was even before he synced anything, so there were even some crazy mismatches of sight and sound. Doing this early and often became very important to getting the exact amount of space needed and verifying that the music had survived the entire tool-chain intact.

It turns out that this was a very good idea indeed.


Getting Real Pt 12. - Running into a Brick Wall While Falling off a Cliff

So, over the weeks, I essentially transcribed and merged all of the music for all of the scoped parts, untangled the notes and gave them a more modern form, and rewrote some minor bits where Clinkster simply couldn't provide the right sounds. I actually went a little too far and even transcribed 4 patterns from the end-credits before Seven put the breaks on me. And you know what? It sounded pretty good. The sound was rich and full and exciting. It wasn't exactly the original music, but in some places it sounded (IMHO) a little bit better than the original, thanks to modern synth technology.

So what was the result? If you remember way back in Part 3, there was a four part process: compose, save, compile, compress.


The result was a 123k Renoise .xrns file. Yikes. It turns out these are already compressed files, the original .xml file in the .xrns file, the one that contains all the note data, was 8,459k. Woah. What's going on here?

Well it turns out, all I'm seeing is step 2 in this process. Again back in part 3 of this series, I discussed the "compile" and "compress" steps. I haven't done those yet! So I copied the .xrns file over to Clinkster's helpful easy_exe folder and ran it only face an explosion of errors. It turns out I had forgotten many of the restrictions I pointed out in Part 3: no effects, maximum velocity of 7F, etc. It took nearly a week to hunt all of those down and get rid of them. Finally I was ready to find out the final size of the music so Seven would have an idea what his byte budget was.

With trepidation I ran easy_exe's "build.bat" and waited, the screen filled with an incomprehensible array of instrument names, note values, velocities and so on. Blueberry's tool was ripping my song apart, atomizing it down to its bare elements. A moment later I saw the following:

Linking...

Uncompressed size of code:  1462
Uncompressed size of data: 34073

Holy cow, my heart was grinding along at triple digit BPMs. The uncompressed music, after going through Blueberrie's atomic music smasher was 34k! I think I may have passed out for a moment, for when consciousness resumed I remember that this was the uncompressed size. I still had to know the result of step 4 "compress":

Final file size: 7998