Author
| PCM player using SCC
|
ARTRAG msx master Posts: 1592 | Posted: October 25 2007, 23:00   |
have you results from the saw teeth test input ?
can you post some files to peek into what is happening?
Are we sure about timing in emulators ?
could a difference in timing the reason for the player not working on the real thing?
|
|
dvik msx master Posts: 1304 | Posted: October 25 2007, 23:29   |
I can't do those sawtooth tests because I can't sample the audio output from my MSX. On the emus I don't need it because I just run the emulator in a debugger so I can see whats going on in the scc emulation.
The timing may be slightly off in emus which may have an impact especially when the period is long. Another thing is that the VDP sometimes has its own clock that may be off a bit from the Z80. All these are reasons why I wanted an adaptive check of the actual period.
The reason why the period can't be set less than 1873 in the replayer may be that the timing of the phase resets may be off a little bit.
|
|
ARTRAG msx master Posts: 1592 | Posted: October 25 2007, 23:50   |
what about doing a self tuning program that adapts the period on the basis of the reading on the rotation of ch 4 ?
disable the ints
start with a guess period
set the 0,1,2,...,31 sequence in ch4
start rotating it
enable the ints
you read the value at VINT and compare the
value with the one red at the previous VINT
If the difference is>0 increase the period
if <0 decrease the period,
if ==0 you got it !
Done as piece of code it could tune the player on each HW it runs!
A sort of self test do be done only at boot time
|
|
dvik msx master Posts: 1304 | Posted: October 25 2007, 23:54   |
Quote:
| what about doing a self tuning program that adapts the period on the basis of the reading on the rotation of ch 4 ?
|
Thats exactly what its doing  |
|
dvik msx master Posts: 1304 | Posted: October 26 2007, 00:08   |
Btw, the reason why the program sounds bad with periods less than 1873 is that the distance between resets of the phase of the channels are limited by the code:
ld de,9800h ; 11
ld bc,18 ; 11
ldir ; 23*18-5
ld bc,14 ; 11
add hl,bc ; 12
ld (9881h),a ; 14
This code takes 468 cycles to execute but to work with the real period 1866, this code can only take 466 cycles. Otherwise you'll get a wrap on the phase of the later channels. To be on the safe side, I would shrink the time it takes to execute this to maybe 450 cycles instead. This will have a very small effect on the phase difference between channels but will always be on the safe side to avoid unwanted wraps.
This is an especially good trade off if it is indeed the case that the phase is reset also if writing to the currently played sample. |
|
ARTRAG msx master Posts: 1592 | Posted: October 26 2007, 00:26   |
IMHO the phase does not count, anyway this code here is exactly 466 cycles
lld a,5
ld de,9800h ; 11
ldi ; 18
ld (9881h),a ; 14
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
LD i,a
ld c,6
and requires interleaving of the data
[edit]
I did an error, now corrected, in the cycle count |
|
dvik msx master Posts: 1304 | Posted: October 26 2007, 00:41   |
It may need to be less than 466 cycles, 450 is a better pick because on some machines the period may be shorter because of timing between SCC and VDP.
I don't think we need to interleave the data for a particular implementation. Its nice to have the freedom of implementing it differently. Hopefully we can be fine with one 60 Hz and one 50Hz implementation but it may be needed with more than one (in case the cycle count needs to be very exact). Performance is not an issue at all here so the code doesn't need to be super optimized for speed so no need to unroll the ldir. The important thing is timing.
|
|
ARTRAG msx master Posts: 1592 | Posted: October 26 2007, 00:54   |
ld a,5
ld de,9800h ; 11
ldi ; 18
ld (9881h),a ; 14
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ldi ; 18
ld bc,22; 11
add hl,bc ; 12
ld (label),a ; 14
Again 466 but without data interleaving, as you have now the data
|
|
dvik msx master Posts: 1304 | Posted: October 26 2007, 01:02   |
Quote:
| IMHO the phase does not count
|
I think it does. Thats why it doesn't sounded good when you tried to lower the period earlier. The thing is that the phase of each channel needs to be reset before it wraps by itself. If it wraps you'll get noise because its playing the wrong sample. Thats why it is important that the distance between resetting the phase of two channels is less than 466 cycles. 466 may work in the emu but not necessarily on a real MSX. |
|
dvik msx master Posts: 1304 | Posted: October 26 2007, 05:04   |
Here is all the source code for both the tool that generates the data (from a 7.6kHz 16 bit raw audio file named fth01.raw).
I also added some code to generate square waves on each channel (the sum of all channels will be a triangle wave I think). I don't have a setup to sample a real MSX but it actually sounds very similar to the emulation. This makes me think that there is a problem with the data, perhaps its not possible to use this method on an SCC. Its too early to make that conclusion but I'm running out of ideas
The replayer includes the adaptive period finder and it prints the period it finds on the screen. The distance of resets between channels is 445 or something which is less than 466 but it doesn't have much impact the sample width is almost correct anyways but I made it lower in case the period on a real MSX would be smaller. But at least my WSX gets the exact same period as the emulator so that is not a problem.
Any ideas are welcome. Would be cool to get this algorithm to work.
Anyways, here is a zip with the files:
http://www.bluemsx/com/demos/fth01.zip |
|
NYYRIKKI msx master Posts: 1504 | Posted: October 26 2007, 07:56   |
Quote:
| The version discussed last two pages doesn't sound as good and doesn't work well on a real SCC yet but it has other great advantages, like only requiring updates in VBLANK and its using only 4% cpu to play decent samples (If the timing can be fixed)
|
Yes, I noticed that you managed to get the CH4 version allready working, but as I said I'm really eager to hear, how this phase shifting idea will turn out... I didn't quite make it... I have newer actually learned to calculate M1 correctly and I may have had some errors also calculating time taken by whole screen update. |
|
dvik msx master Posts: 1304 | Posted: October 26 2007, 19:24   |
The poliphase version works fine in blueMSX and timing looks good. The adaptive period test works fine on a real SCC and there is sound, but on the real machine there are clicks and noise. It would be nice if someone could try the last zip, both the sqare wave and the sampled audio and see what the result is. Best of all would be if someone could run the square wave rom and sample the output from a real MSX. Then I could do some analysis and comparison with the emulator to try to figure out what is wrong.
The correct URL is: http://www.bluemsx.com/demos/fth01.zip
NOTE: The roms only work in 60Hz |
|
ARTRAG msx master Posts: 1592 | Posted: October 27 2007, 01:35   |
Question:
why this:
ld hl,1800 ; <---------------? why this and not 1800/4
ld de,9800h+32*3
ld c,80h
in a,(99h)
.loop:
in a,(99h)
and 80h
jp z,.loop
ld a,(de)
ld (9888h),hl
ld (9886h),hl
cp c
jp z,.end
inc hl
ld c,31
jp .loop
inc hl ;<-------- ? why this
ld (Period),hl
I would look for the frequency around 8KHz and than divide by 4 (i.e . x4 the period)
In this way I am sure of what "real" sample the SCC is playing when VINT arrives
ld hl,1800/4
ld de,9800h+32*3
ld c,80h
in a,(99h)
.loop:
in a,(99h)
and 80h
jp z,.loop
ld a,(de)
ld (9888h),hl
ld (9886h),hl
cp c
jp z,.end
inc hl
ld c,31
jp .loop
end:
call mul_hl_by_4
; inc hl <------------why this ?
ld (Period),hl
this loop should be by far more accurate and gives you the timing
of the last sample at "8KHz" being executed by the SCC
In the other way you get the timing of the beginning of the last
sample at 2KHz, that is too early
Naturally I suggest to adopt the solution in the replayer where
you first put one sample, reset the channel, and than continue for "1/8" secs
move to the next channel do the same
etc
and than you complete the tables in the 4 channels
|
|
ARTRAG msx master Posts: 1592 | Posted: October 27 2007, 01:49   |
PS
your triangle sucks....it is a square wave and even in this way bluemsx shows the clicks and the sample losses
I'll try to do a better test signal
|
|
dvik msx master Posts: 1304 | Posted: October 27 2007, 03:18   |
About the period finder. The idea is to find the exact period so that one full period in the SCC (samples 0-31) will be played between two VINT's. The goal is not to find a period that is a multiple of four. I'm very sure my algorithm will find the best value. Its starting with a period slightly shorter than the expected one. In each VINT, the phase is reset and at the next VINT the currently played sample is fetched. At first the fetched sample will be a low value, e.g. 5 because more than 32 samples have been played and the counter wrapped around. As you get closer to the actual period, the read value will decrease and when the read period is 31 you know that exactly 32 samples have been played. (actually slitghtly less which is why the extra inc hl is there). Its also possible to start with a longer period and decrease it. When the read value is 0 you know that you have a period as small as possible but bigger than 32 samples / frame. Regardless of which way you go, you'll get the same result.
I got your update and will try your test signal instead. At the end I need someone that can sample the result. Did you get your SCC cart yet ARTRAG and if you did, are you able to sample the output?
Btw, the wave I did is not really a triangle wave, its just four square waves that has a phase difference so the sum is somewhat a wave. But it has some good properties which makes it possible to analyze the phase and amplitude difference between the channels and that was why I did it
|
|
|
|
|