Page 5 of 10
Posted: Thu Nov 15, 2012 9:56 am
by Stef
Do the bank / offset / length values refer to the sample you will play ?
If yes so how are you handling the 'length' parameter from Z80 ? With resampling the length will never be equal to 256 and so you have to test sample end at each iteration... There is probably something that i miss...
Posted: Thu Nov 15, 2012 8:25 pm
by Chilly Willy
Stef wrote:Do the bank / offset / length values refer to the sample you will play ?
If yes so how are you handling the 'length' parameter from Z80 ? With resampling the length will never be equal to 256 and so you have to test sample end at each iteration... There is probably something that i miss...
The bank/offset/length refers to the sample playing on that channel. Length is a byte that you load into B for looping (or another 8 bit reg depending on your code). There's also a 16-bit increment the 68000 needs to supply - my fast code has that as an 8 bit integer, and an 8 bit fraction.
The 68000 keeps a start address, a loop address or length, an end address, and an increment. The 68000 generates a bank/offset for the start address, then figures out the shortest length from the following conditions: the next 32KB boundary, the next 256 samples, or the end/loop point of the sample. It stores a length to the minimum, then computes the next bank/offset and the next minimum length. It keeps doing that until it's covered as many samples as needed to reach the next tempo tick, or the channel sample ends.
That relieves the Z80 from having to do those checks and calculations. All it does is load the next address (bank/offset), load a register with the length, load the increment, then resample until the length is zero. NO CHECKING FOR ANYTHING BUT THE LENGTH in that loop. The 68000 side has already guaranteed us that it's safe to ignore everything but the length.
When LENGTH samples are done, it loads the next bank/offset/length/increment and continues. Each channel is done the same way for as many of these packets as needed to resample one buffer worth of samples for the tempo rate.
Posted: Thu Nov 15, 2012 10:37 pm
by Stef
Ok i see now

I guess you send the bank / offset / length list for a total length of your internal buffer used for channel mixing, so the 68k have to fill the list each depending you internal mix buffer length ?
Anyway, the idea is really neat but even with that i wonder which output rate we can obtain... In my 4 PCM players i get 16 Khz with envelop support but i eat almost all Z80 time :-/
Posted: Fri Nov 16, 2012 12:37 am
by Chilly Willy
Stef wrote:Ok i see now

I guess you send the bank / offset / length list for a total length of your internal buffer used for channel mixing, so the 68k have to fill the list each depending you internal mix buffer length ?
Yes. Like my 32X MOD player, you calculate the samples per tick when the tempo is set. The each tick, you process the music, then update the mixer variables for each channel. The only thing more you would do here is to compute the lists of samples for the z80. Since you're not actually computing EACH sample or doing any mixing, it shouldn't add much more overhead to the 68000 side of things.
Anyway, the idea is really neat but even with that i wonder which output rate we can obtain... In my 4 PCM players i get 16 Khz with envelop support but i eat almost all Z80 time :-/
Well, the main mixer code would look like this:
Code: Select all
loop:
EXX
; add fraction to position
LD A,D
ADD A,C
LD D,A
; add integer to position
LD A,L
ADC A,B
LD L,A
LD A,H
ADC A,0
LD H,A
; fetch sample
LD A,(HL)
EXX
; volume[sample]
LD E,A
LD A,(DE)
; mix with buffer
ADD A,(HL)
LD (HL),A
INC HL
DNJZ loop
That's 98 cycles per loop, which for four channels is slightly more than 9kHz. I don't think we're going to get really good rates with mixing with resampling, but a ~9kHz MOD player is still going to be acceptable for most uses... the original Amiga music players were designed around an 8kHz playback rate. Like I said, I've seen 3.5kHz sample playing on the ST (which uses an interrupt to the 68000 to "DMA" the data to the sound chip... using the usp as the DMA pointer, which was pretty smart).
Posted: Fri Nov 16, 2012 9:54 am
by Stef
Even at 9Khz, a MOD player running 95% on the Z80 rocks

I don't have the Z80 instruction set in mind right now but can't we optimize a bit the resampling part by using 16 bit addition instruction ?
Posted: Fri Nov 16, 2012 12:35 pm
by MetalliC
Stef wrote:Even at 9Khz, a MOD player running 95% on the Z80 rocks

I don't have the Z80 instruction set in mind right now but can't we optimize a bit the resampling part by using 16 bit addition instruction ?
you can look at/in
this nice mod-player for ZXSpectrum128 (actualy Russian clone Pentagon128)
I beleive it is pretty well optimised.
Posted: Fri Nov 16, 2012 3:48 pm
by Stef
Unfortunately sources are not available...
Output rate is 10 Khz which is nice but they don't have the infamous bank switch register constraint that we have on the sega genesis. On other hand they can handle 24 effects which is great (i don't think we can do the same in our case).
Posted: Fri Nov 16, 2012 5:59 pm
by Chilly Willy
Stef wrote:Even at 9Khz, a MOD player running 95% on the Z80 rocks
My thoughts exactly.
I don't have the Z80 instruction set in mind right now but can't we optimize a bit the resampling part by using 16 bit addition instruction ?
Currently...
Code: Select all
pointer
HHHHHHHHLLLLLLLL.DDDDDDDD
increment
00000000BBBBBBBB.CCCCCCCC
Maybe...
Code: Select all
pointer
HHHHHHHHLLLLLLLL.DDDDDDDD
increment
BBBBBBBBCCCCCCCC.EEEEEEEE
Where B is just 0. That changes the code to
Code: Select all
loop:
EXX
; add fraction to position
LD A,D
ADD A,E
LD D,A
; add integer to position
ADC HL,BC
; fetch sample
LD A,(HL)
EXX
; volume[sample]
LD E,A
LD A,(DE)
; mix with buffer
ADD A,(HL)
LD (HL),A
INC HL
DNJZ loop
which should be 89 T states instead of 98. That puts us around 10 kHz. If we need BC for something else, we COULD put the increment integer portion into SP (which would mean no stack and no interrupts). You want to avoid using IX/IY for the fastest code since they require an extra command byte, and hence extra T states.
Posted: Fri Nov 16, 2012 11:59 pm
by Stef
Ahh i was sure we could get better

I always use SP in my drivers as when you want best speed you avoid both interrupts and functions

And as you said IX and IY are useless as just too slow to use, too bad, two 16 bits registers wasted :p
Posted: Sat Nov 17, 2012 1:04 am
by Chilly Willy
Stef wrote:Ahh i was sure we could get better

I always use SP in my drivers as when you want best speed you avoid both interrupts and functions

And as you said IX and IY are useless as just to slow to use, too bad, two 16 bits registers wasted :p
Yeah, mostly useless. They can be handy sometimes for temp storage, or in cases where a few more cycles won't affect anything, but not in the inner loop of a mixer.

Posted: Fri Nov 23, 2012 10:35 pm
by Stef
I'm finally to a point i am satisfied with it

It plays smoothly and the audio is now fixed on real hardware.
The only flaw is that i had to split the video in 2 x 4 MB rom as the complete rom takes a bit less than 8 MB... which is already not that big compared to raw size
Download
part 1 and
part 2.
The last part remaining was that sound driver, the demo intensively use the DMA and then PCM playback was very distorted on real hardware.
I fixed that by developing a specific Z80 ADPCM driver which access ROM outside vblank area and now it works perfectly on real hardware Smile
I would like to do a 8 MB version of the rom (without bank access) for mega everdrive but for some obscure reason i cannot get it to work now.... i don't know if this is a bug of the hacked emulator which support that mode or not.
I also plan to do a version with FM music (done by Raijin from Sega16 forum) instead of the poor quality PCM (due to restricted space) but i need a good VGM driver for that, which can play PCM at good rate and ideally access rom outside vblank... and i don't know if that is really possible :-/
I will investigate in existing VGM Z80 drivers and play a bit with them

Posted: Fri Nov 23, 2012 11:22 pm
by Chilly Willy
That sounds much better... some of the best PCM I've heard outside of dedicated sound demos. It's very nearly as good as the pcm streamed from SCD FMVs.
Posted: Sat Nov 24, 2012 12:35 am
by Stef
Thanks

Indeed as soon you take attention about not interrupting the Z80 the PCM sound can be really good

and here i used a poor 4 DPCM codec at 13 Khz, we could have far better PCM quality with more rom space

Posted: Sat Nov 24, 2012 8:14 am
by Ti_
Unhacked Gens and it's mods can open 6Mb roms.
Hacked Gens up to 13Mb.
Mega Everdive can run 10MB Roms. (Kabal's Hack)
The DMA for area >4Mb for hacked Gens may not work (not tested).
Posted: Sat Nov 24, 2012 1:10 pm
by Stef
I used hacked Gens version but it looks like it has some issue with DMA source address > 4MB range...