Page 4 of 5

Posted: Fri Jan 15, 2010 11:47 pm
by Twilighte
Ornament sorted!
The problem was with the way you'd composed the music.. you'd not done it the way i would have done it.. in fact that is very cool cos i wouldn't have found it otherwise :P
I usually assign each channel to a particular area of the music which i carry through the complete piece. However you jump between using a channel for the bass track and using the same channel in a different pattern for the lead. This meant any Ornament tied to the bass track was being carried into the lead track, which is clearly wrong.
It highlighted the mistake i'd made in the code and i corrected it.

The Music player is still very small. After the corrections it is still 1277 Bytes. However this is the first version of Wave, and doesn't support the commands you have used. I will endeavour to incorperate these same corrections into the next version of wave but i suggest for now you keep with this version.
The compiler was doing Wave 2.0 stuff, so i removed that.
The old compiled 1337G was 2701 Bytes whereas the compiler now generates 2303 Bytes. This could be reduced even more if you remove the commands.

There seems to be still a slight problem with the looping, less noticeable than before but i couldn't see the problem in the code at all. Let me know if you can't work with it as it stands and i'll try to fix that one too :P

I'll package everything up and get you the player source asap :)

Posted: Sat Jan 16, 2010 12:04 am
by Chema
Yeah! Great!

I suppose I shall remove the volume control and pitchbends to get a smaller music data... or wait for wave 2.0 :)


Posted: Sat Jan 16, 2010 12:45 am
by Twilighte
Wave 1.1 now released. Its only for fixes to music compiler and player. ... :wave:main

Posted: Sat Jan 16, 2010 5:18 pm
by Chema
Hey Twi.

Been removing all the extra effects not supported on wave 1 and music compiled went down to 2220 bytes.

However I noticed a couple of issues... :(

First one is when trying to play the compiled music loading the file .com and calling #b000. Not sure why, but it sounds wrong.

Anyway using the data and the source of the player you sent me it sounds ok, so no problem... until I noticed that it is jumping over some patterns near the end... at lest jumps over patterns 13 and 14 in the list (pattern 10 repeated twice at that position).

After that everything goes well and the song loops correctly.

Another thing is I am not sure if you still have to add a final $00 to the MusicData. At least it does not end with $00.

Need to experiment reducing the tempo to double the song speed, and then run the IRQ at 50Hz and see how it goes..

Will keep you updated. Thanks for this wonderful utility.

Posted: Tue Jan 19, 2010 12:23 am
by Twilighte
Yep, blame me for not testing it thoroughly enough. Not sure why its doing that with B000 text based compiled music. Because Hires based music is fine.
Anyway, i need to fix the following and will then release Wave 1.02...
1) Fix CBTML so it generates something that sounds like the original
2) Fix CBTML so it generates WTM rather than COM file
3) Fix 00 at end of printout for Printer output option
4) Restore CBTML call within menu (currently disabled)
5) Fix Compiler for pattern 10 issue Chema realised (Fixed tonight)

Am i missing anything else?

Posted: Tue Jan 19, 2010 4:27 pm
by Chema
Nothing I can think about for the main program.

However, as I am interested in getting the sources to add them into my own programs, I might be biased, but I think a couple of add-ons could be interesting. Please be sure that these are just ideas, so you may consider discarding them with no problem:

I would separate the InitMusic from the install of the interrupt service routine, and add instructions about how to call those routines in your own code. That is quite easy, though, as it would be someting like jsr InitMusic before anything else and remember people to jsr PlayTune inside the IRQ (where PlayTune will call ProcMusic and jmp to SendAY). You know, something to help people setting the music inside their own programs.

Also add a routine to stop the music and prepare everything for first-time play (could be called inside initMusic). I am already using this code:

Code: Select all

    ldx #13
    lda #128
    sta ayr_Bank,X
    lda #0
    stx via_porta
    ldy #ayc_Register
    sty via_pcr
    ldy #ayc_Inactive
    sty via_pcr
    sta via_porta  
    lda #ayc_Write
    sta via_pcr
    sty via_pcr
    bpl loop
Not sure if it is correct, but seems to work.

What about a C interface? It is a matter of adding an underscore to the main routines (those which are called from C), so people could issue

Code: Select all

and prototypes in a header file. I could help here, if you wish.

A way to signal a calling program the music has finished (when no looping, for instance setting a variable to $ff or $00 when starting and to the opposite value when finishing) could be nice too!

I also think that it could be really nice to have a bit more control over the tune. I would find great to have control over the main volume, for instance. Or the tempo (it is the second byte in the music data, isn't it?). Or even silencing channels. This way I could, for instance, play the main lead, or the bass section at a lower volume and half the speed, creating interesting variations for in-game usage.

But I am sure that this could mean many changes and some might be difficult, and even useless for most people. So all in all the program is perfect as it is. Just in case you find this ideas useful for something :)


Posted: Tue Jan 19, 2010 7:19 pm
by Dbug
Yes, a C interface is specially easy when functions have no parameters :)

The InitMusic/PlayMusic/StopMusic is how things are done on the Atari ST. Actually the SNDH format is even simple, the program starts by 3 jump instructions. If you call data+0, it initializes the music, if you call data+4 it stops the music, if you call data+8 it replays one frame of music.

The big advantage of this system is that basically you can write universal replayers, music discs, etc... just a matter to load a binary and call fixed offset functions :)

Posted: Tue Jan 19, 2010 8:14 pm
by Chema
That idea is basically what is done (iirc) in any binary library. You start with jump vectors, so you can use them despite any changes made afterwards to the library.

I am not sure this is necessary here. I completely removed those from lib3d and obj3d in the Oric's version and did not use in WHITE+NOISE, because our compiler works with all libs in sources, so labels are solved at compile/assembly time. We could follow this here, if the player+music is in source format.

If Twi wants to keep it in binary format, and offer an interface, then ok, that is the way to go, IMHO.

Posted: Wed Jan 20, 2010 3:31 pm
by Twilighte
Plenty of ideas there. I would also like at some point to change the format of the compiled music so its a bit more efficient. I was thinking that changing the method of pattern compiling need not happen in the editor but in the music compiler stage. I could quantify each pattern checking vertical pattern activity and store only patterns that are used and also look and remove duplicates. Doing it this way would mean the user would see no difference in the editor but the compiled song would be potentially alot smaller.
I need at least to do something to reduce the size of the Impossible mission song which currently compiles to a whopping 8K! :(

Another idea is to have a utility that generates a basic loader (BASIC program with data statements holding the music data and player code) from the compiled file. This could promote BASIC programmers using wave tunes in there programs much more. However not sure how easy to do and also i don't like it so much because it trebles (or more) the amount of code :P

Chema, also is the page alligned constraint too much of a burden to work with and would like it removed (even though it would mean a slight reduction in irq speed)?

Posted: Wed Jan 20, 2010 4:16 pm
by Chema
Twilighte wrote:Chema, also is the page alligned constraint too much of a burden to work with and would like it removed (even though it would mean a slight reduction in irq speed)?
Well, I don't think so, if you have some control over the memory layout. I would do, as I did in 1337, use the .dsb thingy to alling only from where it is really necessary, or where a potential user won't touch the code. Providing a full IRQ service routine the user cannot touch is a bit unconfortable.


Posted: Wed Jan 20, 2010 10:51 pm
by Chema
After a nice chat with Dbug, and a lot of embarrasement in my side, I learned that it is possible to change the rate at which IRQs are produced in the Oric by simply writting a value in the VIA timer 1.

So now my question is, why use a 100Hz IRQ? Couldn't WAVE have a selectable rate, so I could have my music compiled to be played with an IRQ at 50Hz, for instance?


Posted: Wed Jan 20, 2010 11:38 pm
by Twilighte
Ok, finally got 1.02 built and released here.. ... :wave:main

Fixed all my issues from above message and added an extras source file to give some help in implementing the music into your own programs. I seem to be suffering a slight brain block tonight, though i hope this version is stable now.
If it is i can start back on V2.0

Posted: Wed Jan 20, 2010 11:47 pm
by Twilighte
It is perfectly possible to change the irq rate but WAVE is based on the default Oric IRQ speed of 100Hz. This is a bit of a legacy from Sonix days when all songs were 100hz based.
I also prefer 100hz because Ornament based drums have much better bass response at 100hz.

It is a mere matter of changing Timer 1 latch values to a different time base. Currently it is always set to 10,000 but it could conceivably be set as low as 65535 (almost an interrupt a second).. except changing the interrupt speed will also change the speed of anything else the interrupt services.

In fact if you don't mind losing some speed in Ornaments and effects and currently have the music tempo set to 19, you might consider setting the tempo to a quarter what it currently is (about 5) then setting Latches to 40,000.

Code: Select all

    LDA #<40000
    LDA #>40000
Because of the slow Interrupt routines in the ROM, BASIC programmers were advised to set the latch value to a slower rate to speed up their programs in ages past :P

Posted: Mon Jan 25, 2010 10:44 am
by Twilighte
Worked on vertical Patterns for V2.00 Wave last weekend.
Vertical patterns means splitting patterns into individual columns and compiling each as a seperate virtual channel.

With the current wave compiler even if a pattern row just contains a single Volume rest the complete pattern row is compiled.
With this new method it will only compile changes and rest periods therefore dramatically reducing the memory footprint.
The new compiler will also automatically remove duplicates and will only compile patterns that hold changes.
The compiler will not change the Editor environment. The code for the Compiler is now done but i'm yet to build and test. I also need to amend the existing player to handle it.
V2.00 Wave will be backwardly compatible with V1.XX music files.

Posted: Mon Jan 25, 2010 11:35 am
by Chema
That is GREAT. Considering the amount of pattern re-using in my 1337 tune, the amount of data should be reduced quite a lot, isn't it?

Thanks Twilighte!