Autor
| PSG samples
| dvik msx master Mensajes: 1376 | Publicado: Junio 04 2005, 19:23   | Quote:
|
You are right about the speed, but that will also make sample bitrate to vary, so it is not a good idea in this case. I think, that limited memory of MSX makes the speed optimization not important.
|
Then I think the best way is to do as ARTRAG suggested, i.e. do a dec de, ld a, d, or e, jp nz .LOOP thing | | ARTRAG msx master Mensajes: 1802 | Publicado: Junio 04 2005, 21:04   | @dvik
Do you have any measurs of the spikes ?
Are they proportional to the volume changes?
I have developed a program to process the PCM samples in order to extract the succession of the 3 volumes
Each sample I minimize a "metric" that is function of the current sample level and of the volumes I was playing for the previous sample
Sorry for the matlab I try to explay the most uclear passages
The cost for choosing the levels has a term
|x(i)-QQ(:,1)|.^2
that take into account the distortion : QQ(:,1) is the vector of 4096 allowed values
and a term
sum(abs(Q(1+kron(QQ(n,2:4),ones(4096,1)))-Q(1+QQ(:,2:4))).^2,2))
that represents the sum on the three channel of the squared differences between the old levels and the new possible levels (4096)
Actually the matlab expression is ugly and not readable but does what I said.
I assumed that a volume change on channel A gives
|Q(a(n-1))-Q(a(n))|^2
where Q(  is the 16 elemets vector with the DAC response and n is the time
Thus on 3 channels I have
|Q(a(n-1))-Q(a(n))|^2 + |Q(b(n-1))-Q(b(n))|^2 + |Q(c(n-1))-Q(c(n))|^2
the expression
sum(abs(Q(1+kron(QQ(n,2:4),ones(4096,1)))-Q(1+QQ(:,2:4))).^2,2))
compute a vector of 4096 elements with all the values for [a,b,c]
QQ(n,2:4) is the past vector of values
The matlab final expression is
min( abs(x(i)-QQ(:,1)).^2 + 0.7*sum(abs(Q(1+kron(QQ(n,2:4),ones(4096,1)))-Q(1+QQ(:,2:4))).^2,2)) ;
I used a parameter to weigth the sum: 0.7 was empirical
The matlab SNR is 25dB
The MSX play is still far noisier than the PC play but goes better than before (as far as I can hear)
In any case the volumes tend to have less changes than before as you can see from the plot (each color is a channel)
Probably, a part from the weigth factor, the shape of the second part of the cost function could be improved,
but to do this I need measurs of the behaviour of the PSG for each jump between two levels.
If you want the asm and the data send me an email
| | dvik msx master Mensajes: 1376 | Publicado: Junio 04 2005, 22:16   | Please send it to: daniel at vik dot cc
I'm very interested in hearing the difference
| | ARTRAG msx master Mensajes: 1802 | Publicado: Junio 05 2005, 00:35   | Done!
Do you have a measure of spikes?
| | ARTRAG msx master Mensajes: 1802 | Publicado: Junio 06 2005, 01:07   |
About the pre procesing of the samples:
If I get the psg values of the regisers by processing the samples with a cost function that minimize the level transitions in the same channel
the result can be RLE encoded. A play routine can cope easily with RLE and the data are easily converted as (by definition) there are few
transitions.
What do you think about a PC program that does the conversion of 8bit PCM wav files in PSG volumes RLE encoded ?
| | dvik msx master Mensajes: 1376 | Publicado: Junio 06 2005, 02:30   | If the sample player is good enough to use in games/demos I think it is a great idea to have a PC tool to do the conversion. The PC tool could then take any type of wav file (44.1kHz, 22kHz, 16bit, 8bit,...) and generate a nice RLE encoded file. That would be useful.
| | Grauw msx professional Mensajes: 1006 | Publicado: Junio 06 2005, 10:34   | Quote:
| but that will also make sample bitrate to vary
|
Ah, indeed. | | Grauw msx professional Mensajes: 1006 | Publicado: Junio 06 2005, 10:40   | ARTRAG: I compared the output of my sample table on the MAP with the one you sent me last saturday on a real MSX, and yours sounded better (although a little softer)... By the way, I added a simple loader to the player, because well, my assembler has a little trouble (at least takes *very* long time to assemble  ). And now I can also easily play other waves.
ld de,#82
ld a,%001
ld c,#43
call 5
and a
jp nz,Exit_Error
push bc
ld de,SAMPLE
ld hl,#C000
ld c,#48
call 5
and a
jp nz,Exit_Error
ld (LENGTH),hl
pop bc
ld c,#45
call 5
and a
jp nz,Exit_Error
...
Exit_Error:
ld b,a
ld c,#62
jp 5
Or at least, it was something like that. Typing this from memory  .
I also brought an MSX with me to my room in Utrecht, so I can try it out here as well  (if the MSX works, that is, the joystick port is broken and hasn’t got a diskdrive anymore ^_^). | | ARTRAG msx master Mensajes: 1802 | Publicado: Junio 06 2005, 10:47   | Does anyone have done experiments with the different files/techniques and can fill a ranking? My problem is that the performance criteria are subjective as I am not able to do SNR measures on the MSX output.
Actually I use openMSX is anyone able to record the output as wave in order to be processed to do SNR measures (in my case with matlab)?
Once we select the best technique I would propose a player that plays RLE encoded channels. This should be a good compromise between output quality/data size.
| | Grauw msx professional Mensajes: 1006 | Publicado: Junio 06 2005, 15:16   | Note that from the perspective of someone documenting this, I am currently still only looking at playing existing 8-bit samples in the best way possible  . Given the differences between my and ARTRAGs results, I wonder why there is such a difference, and if it can be improved even more.
Until I found that out, pre-converting them on a PC is a second step  .
p.s. the MSX works.
~Grauw | | ARTRAG msx master Mensajes: 1802 | Publicado: Junio 07 2005, 11:00   | @ Dvik & Grauw
I am passing to model spikes. I will use the playback routine I was using before for the sake of simplicity, moreover we do not know if a playback based on tables can be optimal.
This is the playback routine with timings in M and T clocks
PLAY_SAMPLE:
.LOOP: EXX ; 1 4
ld b,[ix+0] ; 5 19
ld d,[ix+1] ; 5 19
ld e,[ix+2] ; 5 19
ld c,$a1 ; 3 11
ld a,8 ; 3 11
out [$a0],a ; 3 11
inc a ; 1 4
out (c),b ; 3 12
out [$a0],a ; 3 11
out (c),d ; 3 12
inc a ; 1 4
out [$a0],a ; 3 11
out (c),e ; 3 12
ld b,14 ; 3 11
.WAIT: djnz .WAIT ; 2 8 if b==0
; 3 13 if b|=0
EXX ; 1 4
rept 3
inc ix ; 2 10
endm
DEC DE ; 1 6
LD A,D ; 1 4
OR E ; 2 8
JP NZ,.LOOP ; 3 10
RET
As far as I can understand the timing of the loop is
5
20
20
20
12
12
12
5
13
12
13
5
12
13
12
191
5
33
7
5
9
11
-----------
447 time clocks
That gives a sampling rate of 3.57e6/447 = 7.986,58 that well approximate my 8KHz
Please check my computations!! I added 1 T cycle per instruction, am I right?
If I well computed
out (c),b ; 3 12
out [$a0],a ; 3 11
out (c),d ; 3 12
inc a ; 1 4
out [$a0],a ; 3 11
out (c),e ; 3 12
The spikes have durations of 11+1+12+1 = 25 between FIRST and second phase and 4+1+11+1+12+1=30 between second and third phase.
If I call a, b and c the volumes of the channels, I get that the correct sample has area (in time clocks)
(a+b+c) * 477
The area means the energy of a spike. Lower energy means lower noise power.
One sample of the PSG output, in the n-th interval, has area
a(n) * 477 + b(n) * (477-25) + c(n) * (477-25-30)
while the previous sample (at time n-1) affect the current sample with the area
a (n-1) * 0 + b(n-1) * 25 + c(n-1) * (25+30)
Thus the error area is (assuming a perfect sample & hold waveform)
x(n)*477 - [ a(n) * 477 + b(n) * (477-25) + c(n) * (477-25-30) ] - [a (n-1) * 0 + b(n-1) * 25 + c(n-1) * (25+30)]
where x(n) is the current sample .
I need to minimize with respect to [a b c] the measure
| x(n) - Q(a)*1 - Q(b)*(477-25)/477-Q(c)*(477-25-30)/477 - Q(b(n-1))*25/477-Q(c(n-1))*( 25+30)/477 | ^ 2 that corresponds to
minimize |x(n) - [Q(a),Q(b),Q(c)]*w1 -[Q(a(n-1)),Q(b(n-1)),Q(c(n-1))]*w2 |^2
where
w1 = [ 1; (477-25)/477 ; (477-25-30)/477]
and
w2 = 1 - w1;
If the waveform is not a perfect S&H, i.e. not squared, things are still computable but getting the exact weights become much more involved.
Do you agree this analysis? Please check the delay I computed. I am not sure about MSX Z80 timings.
Here the matlab file for the optimization:
n=0:15;Q=2.^(n/2);Q=Q/max(Q);Q(1)=0;
QQ = zeros(4096,4);
i=1;
for i1=0:15
for i2=0:15
for i3=0:15
QQ(i,: ) = [ Q(i1+1)+Q(i2+1)+Q(i3+1),i1,i2,i3];
i=i+1;
end
end
end
R=1.2758;
load sample.txt
w1 = [ 1; (477-25)/477; (477-55)/477 ];
w2 = 1-w1;
x = sample(1200:15000)/255*R;
T=[];
[m,n] = min(abs(x(i)-QQ(:,1))); % FIRST SAMPLE
T = [T; QQ(n,: ),n];
for i=2:length(x)
[m,n] = min(abs( x(i)-Q(1+QQ(:,2:4))*w1-Q(1+QQ(n,2:4))*w2));
T = [T; QQ(n,: ), n];
end
y = Q(1+QQ(T(:,5),2:4))*w1 + Q(1+QQ(T(:,5),2:4))*w2 ;
sound(y)
plot (Q(T(:,2:4)+1))
20*log10(norm(x)/norm (x-y))
B = T(:,2:4)';
fid = fopen('sample2.asm','w');
fprintf(fid,'\t db %4d,%4d,%4d \n',B);
fclose(fid);
Actually the result is noiser that the other algorithms wher I discorage any kind of changes....
Any comment?
| | ARTRAG msx master Mensajes: 1802 | Publicado: Junio 08 2005, 01:27   | @ Dvik & Grauw
From openMSX spikes seems to have a duration far longer than the delay between timing offsets in volume changes.
(If i computed well frequencyes in converting the MSX output in wavefiles)
This implies that spikes could be caused by some PSG behaviour and not from
channels randomly combined during the offsets !!!
No spike happens when volume changes are spaced in time more than 0,15 micro second. Strange but tested empirically.
If we structure the playback routine (and the program that does the wav file encoding) in order to have 3 equally spaced volume changes during each sample interval, we could improve our playback a lot.
Any confirm of this insight ?
AR
| |
| |
| |