A question to @BuildASnowman

buildasnowman

#1

@BuildASnowman?

Are you here?

If you are, YaY!

Anyway, How did you do the MIDI to Hopscotch thing?

I didn't know about it until @Rawrbear mentioned it in the 'Leader and Moderator Q&A' topic, and I am, well, Amazed and REALLY curious!

I know you did answer @Rawrbear, but I kinda want a deeper explanation!

Sorry if I'm bothering you!

oh, and, yeah, @oio?

I heard you helped, just tagging you!

Oh, yeah, How did people know about it in the first place?


#2

Ooh, I would love to learn about this too! :smile:


#3

I'll post a full thing later!

@Dude73, @crazygoat


#4

I can't do the MIDI thingy, XD
Do you use it?


#5

Nope, my iPad can't go into apps because it's a school iPad.


#6

Okay, so MIDI hacking works like this.

Basically, @BuildASnowman made a program that turns notes from MIDI files into Hopscotch blocks. So, to use this hack, you would first place a sound block inside your code. Save the project by "x"ing out pf the project. Then, you plug your iPad into a computer with (I believe) iTunes. You then open Hopscotch's program files. Navigate to your .json project (I forgot how :P), then find the note block. Then, delete that block, and copy the notes from the translator. Paste the notes into the program. Save the file and go to Hopscotch. You should see your complex/fast song in there, and it may have so many notes, the app could possibly crash/lag hard!

How MIDI works is that each note has a specific number. This chart explains the whole "spectrum".

How the translator (probably) works is that it turns MIDI codes into Hopscotch code. It's not that complex when you think about it. :slight_smile:


What is the MIDI Hack?
Hopscotch Tutorial!
#7

That's amazing! I might try that sometime. :smile:


#8

Buildasnowman has a video uploaded to YouTube! Check it out it's awesome!


#9

Hey! Sorry I only saw this now! I actually made a video about this, and @Huggingfluffybear made a topic with the video plus some extra info! http://forum.gethopscotch.com/t/best-hopscotch-hack-ever-by-bas/9942

If you need clarification or elaboration on anything, just ask!


#10

can i ask about the code? i should of made it claerer...


#11

I know, but i wanted to know the DEATAULS


#12

@BuildASnowman? <dhdhsjwhddhxgdhdh


#13

I let you know the general concept. That's pretty much the most complex I can think of explaining ¯\_(ツ)_/¯

But then again, @BuildASnowman, what code language did you use?


#14

I used Mathematica. It costs, but it is an extremely extensive and amazing language. (Although I would not reccommend it as a first language)
So, let me try an intuitive explanation of the code. The full code is here:

jsonify[t_]:=(For[i = 1, i <= Length[t[[1]]], i++,
 AppendTo[notes,
  Drop[StringSplit[
    StringReplace[
     ToString[t[[1]][[i]]], {"SoundNote[" -> "", "{" -> ""}],
    ","], -3]]];
For[i = 1, i < Length[notes], i++,
 notes[[i]][[2]] =
  ToExpression[(ToExpression[notes[[i + 1]][[2]]] -
      ToExpression[notes[[i]][[2]]])*1000]];
For[i = 1, i <= Length[notes], i++,
 notes[[i]][[1]] =
  StringReplace[
   ToString[notes[[i]][[1]]], {"1" -> "3", "2" -> "3", "5" -> "4",
    "6" -> "4", "7" -> "4"}]];
For[i = 1, i <= Length[notes], i++,
 notes[[i]][[1]] =
  StringReplace[
   ToString[notes[[i]][[1]]], {"C3" -> "low-c", "C#3" -> "low-csharp",
     "D3" -> "low-d", "D#3" -> "low-eflat", "E3" -> "low-e",
    "F3" -> "low-f", "F#3" -> "low-fsharp", "G3" -> "low-g",
    "G#3" -> "low-aflat", "A3" -> "low-a", "A#3" -> "low-bflat",
    "B3" -> "low-b", "C4" -> "c", "C#4" -> "csharp", "D4" -> "d",
    "D#4" -> "eflat", "E4" -> "e", "F4" -> "f", "F#4" -> "fsharp",
    "G4" -> "g", "G#4" -> "aflat", "A4" -> "a", "A#4" -> "bflat",
    "B4" -> "b", "C4" -> "highc"}]];
For[i = 1, i <= Length[notes], i++, Print["{
             \"section\" : 2,
             \"block_class\" : \"method\",
             \"description\" : \"start sound\",
             \"type\" : 52,
             \"parameters\" : [
               {
                 \"defaultValue\" : \"clickPlayable\",
                 \"value\" : \"" <> notes[[i]][[1]] <> "\",
                 \"key\" : \"and wait\",
                 \"type\" : 51
               },
               {
                 \"defaultValue\" : \"500\",
                 \"value\" : \"" <>
                   ToString[Floor[ToExpression[notes[[i]][[2]]]]]<> "\",
                 \"key\" : \"milliseconds\",
                 \"type\" : 42
               }
             ]
           },"]])

Let's break this down.

Our first section:

jsonify[t_]:=(For[i = 1, i <= Length[t[[1]]], i++,
 AppendTo[notes,
  Drop[StringSplit[
    StringReplace[
     ToString[t[[1]][[i]]], {"SoundNote[" -> "", "{" -> ""}],
    ","], -3]]];

So, to understand this, first you have to understand how Mathematica imports notes. When I import a midi file, the format of each note is this:
SoundNote[D5, {0., 0.496094}, Piano, SoundVolume -> 0.564706]
The D5 is what note to play, the 0 is what second in the song the note starts on, and the 0.4964... is what second the note ends on. The 'Piano' is what instrument it's played on, and, as you can guess, the SoundVolume is the volume of the note.
So, in this code, we first replace the text 'SoundNote' with nothing, and the text '{' with nothing. It then becomes:
D5, 0., 0.496094}, Piano, SoundVolume -> 0.564706]
Then, we split that string by all occurances of commas, which means each piece of text before and after commas become an item in a list. The list has the following items in it:

D5
0.
0.496094}
Piano
SoundVolume -> 0.564706]

Because there is no volume for notes in Hopscotch, and everything I do is on piano, we drop the last 3 items in the list, leaving:

D5
0.

And that is all the first part of the program does! We now have a list of that list for each note.

The Second Section:

For[i = 1, i < Length[notes], i++,
 notes[[i]][[2]] =
  ToExpression[(ToExpression[notes[[i + 1]][[2]]] -
      ToExpression[notes[[i]][[2]]])*1000]];

Now, we have the note. All we need now is how long the note lasts. But remember, Mathematica stores each note's position in the song, not how long to wait after each note. So, what we do is we take the position of the note after the current note and subtract them. For example, if one note came at second 0, then the next at second 2, then the next at second 3, we do the first note:
2-0 = Wait 2 seconds
And the second:
3-2 = Wait 1 second.
Then, because Hopscotch goes in milliseconds, we multiply by 1000 to get how many milliseconds each note is. Now our list, instead of having note positions, has how long to wait:
{D5, 1000}, {G2, 500}

Section 3:

For[i = 1, i <= Length[notes], i++,
 notes[[i]][[1]] =
  StringReplace[
   ToString[notes[[i]][[1]]], {"1" -> "3", "2" -> "3", "5" -> "4",
    "6" -> "4", "7" -> "4"}]];

This is an easy one. Remember, Hopscotch has a limited range of notes. It isn't the whole piano. This code is the main reason my songs sound a bit 'off', like the melody is a bit messed up. It is because we take the low notes on the piano and bring them up to octave 3, the lowest that Hopscotch supports, and take the high notes and send them to octave 4, the highest that Hopscotch supports.

Section 4

For[i = 1, i <= Length[notes], i++,
 notes[[i]][[1]] =
  StringReplace[
   ToString[notes[[i]][[1]]], {"C3" -> "low-c", "C#3" -> "low-csharp",
     "D3" -> "low-d", "D#3" -> "low-eflat", "E3" -> "low-e",
    "F3" -> "low-f", "F#3" -> "low-fsharp", "G3" -> "low-g",
    "G#3" -> "low-aflat", "A3" -> "low-a", "A#3" -> "low-bflat",
    "B3" -> "low-b", "C4" -> "c", "C#4" -> "csharp", "D4" -> "d",
    "D#4" -> "eflat", "E4" -> "e", "F4" -> "f", "F#4" -> "fsharp",
    "G4" -> "g", "G#4" -> "aflat", "A4" -> "a", "A#4" -> "bflat",
    "B4" -> "b", "C4" -> "highc"}]];

Do you know the low-c hack? Well, it works because each Hopscotch note has a plaintext name, which is low-(note) for the lower octave, (note) for the middle octave, and high-(note) for the upper octave. In this code, I replace each of those D5, or G2, or whatever the note is, with Hopscotch's note name. After this step, each note has the two essential items: The note name, and how long to wait.

The Final Section!

For[i = 1, i <= Length[notes], i++, Print["{
             \"section\" : 2,
             \"block_class\" : \"method\",
             \"description\" : \"start sound\",
             \"type\" : 52,
             \"parameters\" : [
               {
                 \"defaultValue\" : \"clickPlayable\",
                 \"value\" : \"" <> notes[[i]][[1]] <> "\",
                 \"key\" : \"and wait\",
                 \"type\" : 51
               },
               {
                 \"defaultValue\" : \"500\",
                 \"value\" : \"" <>
                   ToString[Floor[ToExpression[notes[[i]][[2]]]]]<> "\",
                 \"key\" : \"milliseconds\",
                 \"type\" : 42
               }
             ]
           },"]])

This is actually the easiest to explain, even though it is the longest. This takes our list, and puts it into Hopscotch json form. It takes a pre made template for how a 'start sound' block works in a Hopscotch json, and just fills in the note and how long to wait.
Again, this is all at the end of the video, and it gets even more in depth there. If you have any questions, just ask! :wink:


I'm working to be a leader!
#15

I've been wanting to learn this language, as I've mastered some others.

Would you reccomend it? :D


#16
  1. Are you looking to do anything specfic? Or just general coding?
  2. What other languages do you know?

#17

Not really, just general coding.

I know C++, JavaScript, Lua, and some others. :D


#18

What.

Just...what. XD


#19

My reaction to seeing this at first:

0_0

But it makes sense! I also noticed that {} are replaced with []. :stuck_out_tongue:


#20

Video made it more simple for me :D