Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit/AppGameKit Studio Showcase / create midi music without media (wip)

Author
Message
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 28th Nov 2016 22:32
i have finally got a midi file created from mml code.... no media required!

download it and use code freely and make a cool midi editor or something using agk
im still working on it and going to see about adding modulation/speaker balance/volume editing.

try it out....

also if you have any ideas for mml custom code please let me know. It doesnt currently run all mml code...fyi (just a good portion of it.) i may need to adjust more for midi export

Attachments

Login to view attachments
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 28th Nov 2016 22:35 Edited at: 28th Nov 2016 23:32
oh! forgot to mention it will also produce a wav file using square wav tones... retro! but needs a lot of work!


edit:

so i noticed a bug already. If you try to build multiple midi files it will not work since the memblock used to create the first one still existed.
to fix that just check if it exists and delete it before it trys to create one. I will update the code but not yet. I want to develop the mml code more and then i can post an explanation of how the mml works and
what the commands all do.

try it anyways and let me know what you think. I've already run this on my phone and it creates the midi file no problem on it also and plays back perfectly fine.
I also wanted to let people know that i will release the newly updated QmidiStudio also "the program that i (made/use) to create the mml code in the first place"
using that you should be able to load most midi files in....but not all.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 5th Dec 2016 00:02 Edited at: 5th Dec 2016 00:47
Allot of the tutorials on the midi file format do not go far enough to explain how to write one. information is scattered everywhere and im going to explain it in the best possible way i can.
The worst part that i was stuck on was the variable length values. In order to understand them you will need to be able to break a number down into bits (binary).

This tutorial will help you write a midi file ...but will not help you load one in as there are plenty of midi data types that need to be coded in to accept the data even if its to be ignored.

ok lets start off with the header of the midi file:

(this example is in agk basic)


this next part describes how the midi file is written within the next 6 bytes of data and also describes the delta time division



ok so the header is written and now we can start writing the track that contains all the midi information.
a big problem with the start of writing a midi track is that you need to know how many bytes it uses. It also needs to be written in a four byte value in LSB (least significant byte first)
Agk can not write an integer value using LSB so we need to write our own function for this to work correctly. Also If you decide to find a way that you can count all your bytes before you write them... then be my guest.
however im going to show you all an easy way to do it using a memblock.

So lets just write a value of 4 for now and we will fill in the blank at the end using a memblock.


so if you have the value of how many bytes are to follow then you can replace that number 4 with your value. for now i say lets not worry about it and count the data in the end.
if you noticed.... yes there are 2 functions not described above that are being used.

before calling this command you must dim some array memory to use.


the lsb code function and also notice that i have not gone as far as it could. it could have used all 32 bits but that number is a crazy size that is just not needed.


now that we have a number written across 4 bytes of data it will now need to be written.
here is that second function



that will write out the 4 byte code needed to explain how many bytes are to follow. but if your like me... lets write that value at the end using a memblock.

from this point on will be all the midi messages followed by closing the track.

i will make a new post describing the main midi channel events you could use to make a midi song.

before this lets close this midi file out with no data...lol!



if you were to count the bytes used .... you guessed it that its only 4 as my example was written.

//now your ready to learn the midi messages.... how to write them and how to use variable length data types. i will also teach you the cheating way of counting the bytes after making your midi file and write them in at the end using a memblock.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 5th Dec 2016 00:12 Edited at: 5th Dec 2016 04:03
ok part 2: variable length data

i guess i will do 3 parts to this as variable length data needs to be covered by itself to understand it better.

The idea behind variable length data was to save space if space could be saved. If i was writing a zero delta time event and i had to write it across 4 bytes of data.... well we would be wasting 3 bytes that did not need to be written.

A variable byte is described by the 8th bit being a continuation flag. If the the 8th bit is set on a byte ... this means there is more byte data associated with this number. Once the 8th bit in a byte is set to zero, we then know that was the last byte describing the number.

The function and then i will explain more about it. This example uses only 3 bytes max but you could add to it if you want to.



if you examine a variable byte value... every 8th bit is a carry flag and is not used to calc the actual number

a byte is written in this order [87654321] since the 8th bit can not be used to describe the number i will show you some examples.

a number of 127 can fit in a single byte

[8]=0
[7]=1
[6]=1
[5]=1
[4]=1
[3]=1
[2]=1
[1]=1

that in binary is 01111111 and is the max value using a single byte in variable length data

if we had a value of 255... well this can no longer be described in a single byte since the 8th bit is a carry flag... instead we will write it as a 2 byte value

255 as binary normally would have been written as 11111111 however now it will be written using 2 bytes in variable length quantity.

[every 8th bit is a continuation flag]

255= [10000001] [01111111] notice the 16th bit is set to 1. this tells you that there is more bytes describing the size of the number. The 8th bit is now set to 0 since there is no more bytes needed to describe this number.
so the only bits used in those 2 bytes to describe the number 255 was then 9th bit,7th,6th,5th,4th,3rd,2nd,1st bits only. the 8th bit was set to 0 to describe that it was the last byte. the 16th bit was set to 1 saying there was more byte data to follow in order to describe this number.

your code must use a variable delta time to describe when an event should occur .

if you need more help understanding this... ask me any questions you may have.

my next post will be the midi messages used to compose your song.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 5th Dec 2016 00:51 Edited at: 5th Dec 2016 03:54
ok part 3...
the midi messages and delta time.

all notes that are turned on must be turned off at some point in time. failing to do this will sound horrible and all your notes turned on will just stay on.
all midi messages are described after the associated delta time wait interval.

so if no time has passed by then you would use a delta time of 0 saying that this event occurs at the same time as the last event message.

advancing this number means that from this new event being posted.... this much time has elapsed. every new event after this point has also advanced this far.

-start of song-
so if i turn a note on at delta time 0 (start of song)
i turn that same note off at delta time 32
-end of song-

this means that a 32 delta time has passed before turning the note off
you can stack all the channels events in there using the same delta times or advancing your song as needed. changing the delta time will advance the whole song forward. After advancing the song forward you will use 0 delta times to describe the rest of the activity that needs to be performed at the same time.

changing the delta time means to change the time since the last events that occurred. This number describes how much time has passed since last event. Do not keep adding bigger and bigger values to the delta... thats not how it works.

if i had data every 4 delta time cycles .... my delta advance number would always be 4 and then 0's to describe all the events that happen at the same time.

ok some code:

set midi tempo:


lets Analise that:
after we set our variable byte delta time we must call the midi command. I see there is 2 new functions being called that have not been defined yet....so lets define them first.



another new command involves setting a nibble inside a byte.



2 nibbles are used inside a byte to describe what midi event is happening. in this case it was FF "hex" 255 decimal.

the command FF 51 (using 2 bytes or... 4 nibbles in our case) this tells the midi player to set the tempo which is written in 3 bytes of data

so <deltatime> <FF> <51> <03> <byte3> <byte2> <byte1> written as msb. my command writes it as lsb but is then saved as msb manually
you must use 3 bytes of data to describe this tempo. i could be wrong.... but for this examples sake.... dont change it.

the tempo is in beats per minute. since the start of my header says im using a 32 delta time division... it will take 32 delta time frames to hit a quarter note using 4/4
to write a 32nd note delta time would equal 4 and the sizes go up from there. Since my previous midi work involves the smallest note a 32nd note, all my delta times advance by 4

once you get passed this the rest of the events are easy i promise!


all the commands i have written to write a midi song.

set midi channel volume

fn=file number, deltatimepassed, channel, value)

the value can be 0 to 127 max volume for the channel
channel 9 is the standard drum kit (fyi)
the channel range is 0-15 and 9 is the drum kit.


set midi channel balance


filenumber,deltatime,channel,value
the channel range is 0-15
balance is 0 to 127
0 = left
63 center
127 =right


midi channel modulation


filenumber,delta,channel,value
the modulation wheel is 0 for off..... 127 max


midi channel pitch change


0 would change the pitch of notes on the selected channel to be 1 tone lower
63 would sound normal
127 would change the pitch of notes on the selected channel to be 1 tone higher


change a channel instrument


its setup for an instrument value of 1 to 128 but actually subtracts a value
normally this would have been 0-127
1=piano and so on.... the instrument numbers can be looked up online.


turn a midi note on


turn a midi note off


midi tones are in the range of 0-127... you will need to do some homework to see what numbers are what notes at what octaves.

thats all the messages needed to write a midi file. after this you would write the close track command that i have on the first post of this tutorial.

looks like this:



now like i said before we will cheat and fill in that bytes to follow value. remember above i had written 4. we now need to count all the bytes used inside our track and can do it like this.



so we saved the file... loaded it back in as a memblock
we subtracted the header bytes and part of the track header to get the total bytes to follow.

then we write it in the correct byte order.
delete the original made file
save the new one...

thats it.

ask plenty of questions if you gotem. see my example on first post if you want to see the code in action. Some of these new functions need to be added in however but are posted in this very post.
hope that helps.... it should make it easy to create a music editor now using this.
george++
AGK Tool Maker
17
Years of Service
User Offline
Joined: 13th May 2007
Location: Thessaloniki, Hellas
Posted: 5th Dec 2016 19:03
Very interesting information here SoftMotion3D.
I have no knowledge in music in general and I suppose it is useless to me
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 5th Dec 2016 21:42
Ya im hoping this can be used for a music editor or even a game simular to rockband.

I am working on an editor right now and i will post it when its ready.
Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 11th Dec 2016 16:11
YOU ! ARE ! THE ! GREATEST ! You are my hero. Works on AndroidTV 6.0+ (ForgeTV), also under Windows, but MIDI does not work in Chrome, but works if created Wave before. LoadMusic now works with MIDI? The instruments sound a little bit strange when using creating the Waves. And the MIDI-Play will use the wavetable from the System the game is running on, Softsynth or Soundcard, so it could sound different on every system it would deployed from what I understand.

Great work. Keep it. Best regards.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 11th Dec 2016 16:52 Edited at: 11th Dec 2016 16:58
Quote: "LoadMusic now works with MIDI? The instruments sound a little bit strange when using creating the Waves. And the MIDI-Play will use the wavetable from the System the game is running on, Softsynth or Soundcard, so it could sound different on every system it would deployed from what I understand."


ya midi has worked since the beginning actually. I had midi running on agk v1 if i remember correctly.
You are right that the midi instruments do not sound the same across different systems. Its not a big deal though. This is where the recordsound function would be great. you could play back the midi and capture it to a wav file if that was working. good news is that every device should be able to play midi unless your pc mysteriously has no sound card.

Also if a phone was used to create a midi file.... (music) it could be recorded to pc by plugging it into the line in jack using a sound recorder application.
if you can transfer the midi file back to pc... it could easily be edited again and recorded to wav as well. <-that should be easy to do!

I didnt get much working with the wav samples. what i did learn is that you cant take the average of the sounds mixing.... you must add them all together. If you do not add them together you
will miss sounds fading out and in. it will just sound wrong. You must control the output for each wav sound getting mixed to prevent distorted sound. In the end... they need to be added together to mix properly.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 11th Dec 2016 17:12
Quote: " but MIDI does not work in Chrome,"

i wonder if this is an html thing? maybe midi does not work using html? can anyone using html export confirm this as i am not setup to test it right now.

does an agkv2 app exported to html play midi files?
Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 11th Dec 2016 18:41
@SoftMotion3D,

I am trying the other way arround. I could use any music software to make a wave, ogg, mp3 file, but they would be very large, when using a lot of music. About 3 MB for 3 min. of music. For android my complete program (apk) should not be over 100 MB. So I want to save every space I could. MIDI does not work in the browser on it's own, because it's no HTML5 standard. MIDI player in the browser will fake it with FLASH or converting the MIDIs into MP3 before you can listen to them on the server side. Or they will generate the instrument-sounds in Java Script, like you do it with MML.

I want to use MML or something like that also to generate gamesound effects. It would be also great, to be able to have a function like LoadMusicMML (1,"MySong.MML"), or LoadMusicMIDI(1,"MySong.MID") which would generate a Memoryblock for playing it like a song.

With MML I have the problem, that it seems, that there are also differences in the syntax an one program can generate MML, but another can't play the MML from the program before and so on.

I tried some player and composer from here, but I don't know, how I get my own music in an easy way to your AppGameKit program.
http://woolyss.com/chipmusic-mml.php

Maybe you have time and can make a little demo, where a MML-file (text file) would converted and loaded into your array like you do it in music.agc (I have no unpublished qmidi studio yet, so I don't know, how to test other MML-music )

Thanks for help.
Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 11th Dec 2016 18:46
For example, how would I get this song to play?

http://www.libspark.org/wiki/Craptune

SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 11th Dec 2016 20:04
ok.... let me see if i can build a utility to convert midi to mml code or some small format without using qmidi studio.
and your correct that all mml code seams to differ from app to app.
petite basic for gameboy ds uses something very simular to mine. infact there is just a few things different that i added in.
looking at that mml code... ya its a mess! You want to save space correct?

i think if we design a standard mml format that can control volume,modulation, and pitch that we would have it made.
with those modifiers you can playback some very good sounding tunes.

are your tunes currently in midi file format? post one on this thread and i will convert it to mml code for you if you would like to experiment.

also see if agk produces a smaller midi file then the one you send me and if it still sounds the same.





Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 11th Dec 2016 22:35
Currently I have no music. I would make the music after knowing, that I can play the format. The backup plan would be, to create music and use ogg instead and reduce quality and quantity of the songs. I though of using a tracker program. And my format could be S3M or I could use HivelyTracker. But I can't replay S3M yet, nor HVL/AHX. MML is also a little bit complicated because MMLTalks are down and most of the documentation is in Japanese. SiON with FLASH was able to replay MIDI with your own "MML like Instrument definitions". I am looking for a tune in the direction of the MegaDrive / Genesis. http://www.deflemask.com/ But with defletmask there is the problem, that you have to emulate the soundchips instead of synthesize the instrument sounds.

How would I manipulate the tunes of the instruments? Do I have channels like on the C64. And can combine some basic tunes? Do I have Oscelators? I am thinking of having about 5 to 32 values to play with to generate an instrument. And the music itself could be in channels or tracks, with Instrument-ID and the notes to play.

Like Sonant Live
http://sonantlive.bitsnbites.eu/

In my understanding some tracker formats do the same like MML with the difference that MML is readable by humans.

... I see. I can use createtonemb(), but it is very basic like we created it before / converted it from the AudioPlayground (PureBasic), but not deeper. Maybe we can create more advanced Instrument-Creating with some basic functions like mixing waves together and creating new tunes from stratch with f.g. adding 12 sinewaves with different frequenzies together to get an instrument sound. I think, the Instrument creating function is lagging the ADSR (curve)

So I could imagine for having a hybrid music format. MIDI for the notes, and a Wavetable WAVE, with data, where the instrument wave begins and ends. So one wave file with some kBytes, containing e.g. SingleCycleWaves and merged together to one file.

This would be a kind of MOD (Tracker Module), but without the tracks.




Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 11th Dec 2016 22:37
For now, I can do MIDI. That would be good. And later changing the instruments would be great.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 11th Dec 2016 22:47
ok i see.

let me build a music tracker editor that defaults to midi. I can build in some custom wav table editor with some options and hopefully you can simulate some new instruments with it.

look at this for example:http://www.feilding.net/sfuad/musi3012-01/html/lectures/009_hearing_IV.htm#notesandharmony

this shows us how a few of the instruments look like visually.

i could make an editor that you could draw those in and hopefully set to the right rate will sound like the instrument playing.
I need to build a new editor from ground up to integrate such a thing to see if it even works. I think it will work.

will take me about a solid month to develop a new midi editor/tracker. I'll start the project right now.
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 12th Dec 2016 02:52
so im thinking of a few different views and it needs to work on mobile.
this is a quick shot of an idea so far that i attached.

I would like to use a side scroll with this. instead of a fixed screen flipping pages i would like to scroll it left and right.
I also think that where the keyboard is it should scroll over and reveal all functions. Depending on what function is selected it will display the editor window for it.

Got lots of work to do...so i better get at it. Any ideas for it?

Attachments

Login to view attachments
Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 13th Dec 2016 14:29
You don't have to think mobile in the first place. For Mobile your buttons have to be much bigger, but on a real Screen you could type in text, using the mouse, or using the keyboard for making notes.

I like SoundClub v2, if you could, you can look at the DOS-Version (SoundClub v1) also.
SoundClub v1 can import/export MIDI, the Windows-Version not

Also the export from SClub v2 to MOD makes them broke, the only ways are WAV (big filesize) or S3M, not supported by SClub V1.

In SClub v1 I could do my MODs, and export the Samples for the instruments as RAW-Wave-data, and the melody as MIDI.
Would this help? So you would save the time for creating a complex editor.


Win
http://www.bluemoon.ee/history/scwin/
Dos
http://www.bluemoon.ee/history/scdos/index.html
With DOS-Box
http://www.dosbox.com/download.php?main=1

Maybe supporting S3M would be the best way, for me it would be great, to have Standard S3M support. Without AdLib or anything fanzy.

http://lclevy.free.fr/mo3/s3m.txt

Maybe we could decode it together. Or ripping the Samples and extracting the Melody and convert that to your standards.

Thanks for help.
Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 13th Dec 2016 14:37 Edited at: 13th Dec 2016 14:38
@mobile

Here is a project I have done in Scratch, it had a very tiny screen resolution (480 x 360) in mind.
https://scratch.mit.edu/projects/767674/

The idea is, to have music-blocks like in Magix Music Maker or in DanceEjay, but every block contains drum- and note-data. Every block could be edit by the panel in the up, and in the middle you could choose your tools for that.

It does not work, because Scratch slows down with so many programs inside, and also the sound support was not great in 2009, but the idea is stilll there, to store music in pictures, also for mobile platforms, or for publishing over twitter, tumblr and instagram

Attachments

Login to view attachments
SoftMotion3D
AGK Developer
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: Calgary,Alberta
Posted: 13th Dec 2016 17:27
I was thinking of the magix approach also. Id make it so you could edit the music within the blocks.

Id like the app to work on a tablet at the least. I tried that mini keyboard on the phone and its near impossible to press what you want.

Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 14th Dec 2016 13:04
If your resolution is about 960 × 640 and 3,5" (iPod Touch 4., iPhone 4) or a little bit more on iPhone 5, you could only get a couple of Buttons on the screen. You can do you piano, but not for touch, only for showing, or you have to implement something like scrolling or zooming into the pinao-bar.

For mobile, if not iPad Size, you can only focus on one tool per screen. And with high resolution of the displays, your buttons will take nearly 64 x 64 pixel for finger tips. You could make it smaller, but this woul be not better in most cases. I think your piano could have at max to octaves at the same time on a phone, but for faster play with real fingers only one octave is optimal in size.

Or you aiming on iPad, Surface, Wacom Companion tablet PCs with multitouch. But they have also mouse, stylus or pencil

Attachments

Login to view attachments
nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 21st Dec 2016 00:19
I'd always fancied the idea of mod support. It's now actually possible to write a native mod/XM player in T1 but it would be a lot of work. Seems like it would be SOOO much easier to add external lib support
Xaby
FPSC Reloaded TGC Backer
17
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 26th Dec 2016 12:29 Edited at: 26th Dec 2016 12:34
Maybe we could work all together and create a native MOD-Library like FMOD or Open MODPlug

MOD 4 Channels, 8 Bit per Sample
S3M 16 Channels, 16 Bit per Sample, without Adlib FM

and later things like AHX or Hively Tracker HVL


I would also like to see native ADPCM (IMA ADPCM) decompressor / compression for Audio Samples. To be able to save 16 Bit Samples with only 4 Bit memory ussage like it was used in N64 Cardridges and I think also in some SNES titles.

So there would be a ratio from 1:4 possible without a great processing overhead. And with some looping functions, it would be possible, to have background Music without vocals nearly small like MP3, but with better quality and less use of CPU performance.

A format which can have S3M Songs, but ADPCM Samples would be great.

Found this (ADPCM for Voice signals implementation Encoder, Decoder:
https://www.mp3-tech.org/programmer/docs/adpcm.pdf

Login to post a reply

Server time is: 2024-11-21 22:47:02
Your offset time is: 2024-11-21 22:47:02