Bad Apple demos

A place to discuss general QL issues.
stephen_usher
Gold Card
Posts: 433
Joined: Tue Mar 11, 2014 8:00 pm
Location: Oxford, UK.
Contact:

Re: Bad Apple demos

Post by stephen_usher »

OK, I have music now, but it really shows up the variable frame rate.

https://youtu.be/npDgDDuBh00

P.S.
The source can be found here: http://www.lingula.org.uk/~steve/share/ ... ec2.tar.gz
And the HD floppy disk image containing the executable and sample file (and a SuperBASIC program to play the tune here: http://www.lingula.org.uk/~steve/share/ ... r.qlhd.img


stephen_usher
Gold Card
Posts: 433
Joined: Tue Mar 11, 2014 8:00 pm
Location: Oxford, UK.
Contact:

Re: Bad Apple demos

Post by stephen_usher »

By the way, I'm always amazed by Marcel's talent. I feel a bit of a dunce beside what he manages.


User avatar
NormanDunbar
Forum Moderator
Posts: 2273
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Bad Apple demos

Post by NormanDunbar »

Marcel has a brain the size of a planet.
I've always said so.

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: Bad Apple demos

Post by mk79 »

stephen_usher wrote:I did find a PT3 player for the Atari ST, but it's written in impenetrable Pascal for some reason. Even a tracker format could be analysed.
I have ported/written a native PT3 player for the QL. Considering that even after that I still don't understand the format 100% I stand by my assessment that it's not a direction you'd want to go ;)

Marcel


User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: Bad Apple demos

Post by mk79 »

stephen_usher wrote:OK, I have music now, but it really shows up the variable frame rate.
OK, that is actually pretty cool :-) Especially considering that it's still written in C. While it's pretty hard to beat modern compilers with hand-written assembly code XTCC is non-optimizing and the code will always be slower than probably even the worst hand-written code ;) But for a stable frame rate you need to employ the 50Hz poll interrupt. which is maybe not impossible from C but at least very hard.
Besides here you're entering an area where I am completely clue and talent-less: music! Still, thanks for the kind words ;)

Cheers, Marcel


User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: Bad Apple demos

Post by mk79 »

NormanDunbar wrote:Marcel has a brain the size of a planet.
I've always said so.
Maybe that's the cause for my constant headaches, not the lack of sleep as I suspected ;) Anyway, thanks, you're making me blush :-P

Cheers, Marcel


stephen_usher
Gold Card
Posts: 433
Joined: Tue Mar 11, 2014 8:00 pm
Location: Oxford, UK.
Contact:

Re: Bad Apple demos

Post by stephen_usher »

mk79 wrote:
stephen_usher wrote:OK, I have music now, but it really shows up the variable frame rate.
OK, that is actually pretty cool :-) Especially considering that it's still written in C. While it's pretty hard to beat modern compilers with hand-written assembly code XTCC is non-optimizing and the code will always be slower than probably even the worst hand-written code ;) But for a stable frame rate you need to employ the 50Hz poll interrupt. which is maybe not impossible from C but at least very hard.
Besides here you're entering an area where I am completely clue and talent-less: music! Still, thanks for the kind words ;)

Cheers, Marcel
As for the music bit. I used the on-line document about how to convert other BASICs to SuperBASIC to get the beep values for the notes and then used a synth app on my iPad to work out the notes.

Seeing as I had a whole byte to play with in the codec format now, I made the top three bits the duration of the note in (x 1600 for the beep duration) and then a look-up table for the bottom 5 bits of pitch (as there are, I believe, only 26 usable values for beep).

The encoder then stuffs the sound info into the "new frame" line header of the relevant frame to start the beep.

The decoder looks at the sound info part of the header every new frame. If it's non-zero then it just uses the library's do_sound() function to throw it at the IPC. I can add a delay into the "new frame" code by giving up 'n' job slots using MT_SUSJB, which gives a very basic synchronisation. Still, it's only rough and ready.

As for the coding, I do try to write the C bearing in mind what it might be translated to in assembler. e.g. creating a "word" value using integer arithmetic + shift rather than two one byte writes as the former variable arithmetic should go into a register (especially if it's a (register short)) and then a MOVE.W into memory. That's if the compiler is sane, which it probably isn't.


stephen_usher
Gold Card
Posts: 433
Joined: Tue Mar 11, 2014 8:00 pm
Location: Oxford, UK.
Contact:

Re: Bad Apple demos

Post by stephen_usher »

Bother! I forgot to update the include/m4v.h file in the source archive so I can't post the musical notes look-up table. I'll have to fix that when I get home.


stephen_usher
Gold Card
Posts: 433
Joined: Tue Mar 11, 2014 8:00 pm
Location: Oxford, UK.
Contact:

Re: Bad Apple demos

Post by stephen_usher »

OK, file updated with proper m4v.h file, anyway, here's how the music works:

The decoder uses the following value to IPC note table:

Code: Select all

int pitch_table[] = {
	41, /* A  */
	38, /* A# */
	36, /* B  */
	33, /* Middle C */
	31, /* C# */
	28, /* D  */
	26, /* D# */
	24, /* E  */
	22, /* F  */
	20, /* F# */
	19, /* G  */
	17, /* G# */
	15, /* A  */
	14, /* A# */
	12, /* B  */
	11, /* C  */
	10, /* C# */
	9,  /* D  */
	8,  /* D# */
	7,  /* E  */
	6,  /* F  */
	5,  /* F# */
	4,  /* G  */
	3   /* G# */
};

#define DURATION_FRAMES 3
#define NOTE_DURATION 1600
So, the encoder merely has to store the offset in this table in the video file. You'll also note that each music tick is actually 3 frames long. The 1600 is the multiplier for the duration of the note as given to the IPC. The docs say that the BEEP duration is a multiple of 72ms but I'm not sure that this is correct.

The actual music itself is currently hard coded into the encoder as two arrays, one holding the musical note table offset and the other the duration in music ticks.

Code: Select all

unsigned int notes[] = {
        6,8,9,11,13,18,16,13,6,13,11,9,8,
        6,8,9,11,13,11,9,8,6,8,9,8,6,8,9,
        6,8,9,11,13,18,16,13,6,13,11,9,8,
        6,8,9,11,13,11,9,8,6,8,9,8,6,8,9
};

unsigned int duration[] = {
        2,1,1,1,2,1,1,2,2,1,1,1,1,
        1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,
        1,1,1,1,2,1,1,2,2,1,1,1,1,
        1,1,1,1,2,1,1,1,1,1,1,1,1,1,2
};
The encoder only sets the value in the audio byte in the frame header of the frame which should play a note, so the decoder doesn't have to do this calculation, only do what it's told.


User avatar
Cristian
Aurora
Posts: 962
Joined: Mon Feb 16, 2015 1:40 pm
Location: Veneto

Re: Bad Apple demos

Post by Cristian »

mk79 wrote: an area where I am completely clue and talent-less: music!
So, after all, your planet-sized brain is more similar to Mars than to Jupiter :-)


Post Reply