Autor
| PCM player using SCC
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 24 2007, 22:34   |
I've done some tests but the result so far is quite horrible (much worse than the previous demos). Its possible to hear the samples being played but there is a lot of clicks. I'll see if I can improve it somewhat and post a demo.
|
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 24 2007, 23:14   |
I have a plan  |
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 24 2007, 23:37   |
tell me!
|
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 24 2007, 23:45   |
my matlab tests
[Y,FS,NBITS,OPTS]=WAVREAD('handel3.wav');
%Y=Y(1:128);
ph1 = Y(1:4:end);
ph2 = Y(2:4:end);
ph3 = Y(3:4:end);
ph4 = Y(4:4:end);
ch1 = ph1;
ch2 = ph2 - ch1;
ch3 = ph3 - ch1 - ch2;
ch4 = ph4 - ch1 - ch2 - ch3;
for i=2:size(Y)/4
ch1(i) = ph1(i)-ch2(i-1)-ch3(i-1)-ch4(i-1);
ch2(i) = ph2(i)-ch1(i)-ch3(i-1)-ch4(i-1);
ch3(i) = ph3(i)-ch1(i)-ch2(i)-ch4(i-1);
ch4(i) = ph4(i)-ch1(i)-ch2(i)-ch3(i);
end
z = zeros(size(Y));
C1 = kron(ch1,[1;1;1;1]);
C2 = kron(ch2,[1;1;1;1]);
C3 = kron(ch3,[1;1;1;1]);
C4 = kron(ch4,[1;1;1;1]);
z = C1 + [0; C2(1:end-1)] + [0;0; C3(1:end-2)] + [0;0;0; C4(1:end-3)];
plot (Y)
hold
plot(z,'ro-')
|
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 24 2007, 23:53   |
I wonder if some of the noise is because of overrun on these matlab calculations. Do you have any good ideas to make sure the values don't wrap?
The idea is very simple and I think it will give very good results (at least on paper). In VINT, we do:
1. Update ch1: sample 0-16
2. Reset ch1 phase (1 and 2 should take exactly 468 samples (or whatever it is)
3. Do same thing for ch2-ch4 (Now beginning of all waves are updated, note that sample 31 is still old value which we want)
4. Update remaining 16 samples for all channels (this will not impact playback since all channels are at sample 0 or 1
So this means that we can do all updates without any impact of playback (I think).
|
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 24 2007, 23:57   |
That was indeed one big problem. For testing I divided the input samples by 16 and then most clicks went away (but noisy since now its only a 4 bit player). Any ideas on how to fix this without lowering the amplitude?
|
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 24 2007, 23:59   |
Let me try to understand
if you reset volumes of the the SCC as fist thing at each VINT
you can compute the first 4 samples independently by the
current values of the channels, as they where the first
4 samples played at the beginning of the file.
Is this your proposal?
|
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 25 2007, 00:03   |
Its actually quite simple. Since we don't have enough time to update all samples + reset the phase for a channel in less than one sample, I simply copy as much as I can fit and then copy the rest after all four channels are updated. This will give a very smooth transition with almost no added noise if the period is selected correctly based on the frame rate.
But how do I solve the problem with overflow in the generation of the samples?
|
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 25 2007, 00:04   |
no it wasn't
[edit]
Why you get overflow?
Do you refer to the problem I spotted?
i.e. the fact that each chunk of 32 bytes
depends on the values played during the
previous chunk?
Or you simply say that fix point 8 bit math is exceeded by the
formulas to generate the channels ? |
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 25 2007, 00:10   |
The problem can be illustrated this way. We have:
ch4(i) = ph4(i)-ch1(i)-ch2(i)-ch3(i)
if ph4(i) = 0, ch1(i)=ch2(i)=ch3(i)=127
then ch4(i) = 0-127-127-127 = -381
which is outside the range of a signed char.
EDIT:
Quote:
|
Or you simply say that fix point 8 bit math is exceeded by the
formulas to generate the channels ?
|
Yes
EDIT2:
Quote:
|
Why you get overflow?
Do you refer to the problem I spotted?
i.e. the fact that each chunk of 32 bytes
depends on the values played during the
previous chunk?
|
This is not a problem if the period is set correctly. |
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 25 2007, 00:16   |
I'm on it
|
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 25 2007, 00:16   |
Great  |
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 25 2007, 00:19   |
U've mail
[Y,FS,NBITS,OPTS]=WAVREAD('handel3.wav');
%Y=Y(1:128);
Y=round(Y*128);
ph1 = Y(1:4:end);
ph2 = Y(2:4:end);
ph3 = Y(3:4:end);
ph4 = Y(4:4:end);
ch1 = max(min(ph1,127),-128);
ch2 = max(min(ph2 - ch1,127),-128);
ch3 = max(min(ph3 - ch1 - ch2,127),-128);
ch4 = max(min(ph4 - ch1 - ch2 - ch3,127),-128);
for i=2:size(Y)/4
ch1(i) = max(min(ph1(i)-ch2(i-1)-ch3(i-1)-ch4(i-1),127),-128);
ch2(i) = max(min(ph2(i)-ch1(i)-ch3(i-1)-ch4(i-1),127),-128);
ch3(i) = max(min(ph3(i)-ch1(i)-ch2(i)-ch4(i-1),127),-128);
ch4(i) = max(min(ph4(i)-ch1(i)-ch2(i)-ch3(i),127),-128);
end
z = zeros(size(Y));
C1 = kron(ch1,[1;1;1;1]);
C2 = kron(ch2,[1;1;1;1]);
C3 = kron(ch3,[1;1;1;1]);
C4 = kron(ch4,[1;1;1;1]);
z = C1 + [0; C2(1:end-1)] + [0;0; C3(1:end-2)] + [0;0;0; C4(1:end-3)];
close all
plot (Y)
hold
plot(z,'r-')
save ch1.txt ch1 -ASCII
save ch2.txt ch2 -ASCII
save ch3.txt ch3 -ASCII
save ch4.txt ch4 -ASCII
save ph1.txt ph1 -ASCII
save ph2.txt ph2 -ASCII
save ph3.txt ph3 -ASCII
save ph4.txt ph4 -ASCII
|
|
ARTRAG msx master Mensajes: 1802 | Publicado: Octubre 25 2007, 00:21   |
Now chX cannot exceed 8 bit precision
Rounding and clipping are taken into account in the formulas
[edit]
clipping cannot be avoided, but this version should work
better as it can cope with the errors correcting them using
the sum of more channels
|
|
dvik msx master Mensajes: 1376 | Publicado: Octubre 25 2007, 00:48   |
The result is very good  I'm surprised. I haven't tested on a real MSX yet but I will soon.
Note that this is 7.6kHz and the updates are done once every VBLANK. So a very CPU friendly PCM player.
Note that this version only runs on 60Hz machines. A 50Hz version will come soon.
http://www.bluemsx.com/demos/fifth_60Hz.rom
|
|
|
|
|