Schrijver
| playing samples on msx
| norakomi msx professional Berichten: 861 | Geplaatst: 06 September 2005, 16:43   | Quote:
|
There are "ready sample players" for PSG, look for MUST by Ricardo Bittencourt! (I also use the same "must technology" in a routine made by Adriano on my game "Show do Milhão", with very nice results)
|
cewl, Id like to have a look at that game, if possible....... | | NYYRIKKI msx master Berichten: 1510 | Geplaatst: 09 September 2005, 18:31   | As questions about samples are asked every once in a while, I decited to write a quite a complete article about this issue. Let's see if I can make the biggest forum post posted so far
I hope you find this interesting, this document also contains some new information about SCC.
Playing samples on MSX & Z80. 0.9b Made by: NYYRIKKI 2005
---------------------------------------------------------
There are many ways to play samples on MSX. MSX-Audio and Moonsound has even
dedicated hardware to play samples, but these hardware solutions are not in
scope of this document.
From this document you'll find, how to play samples following on devices:
- Covox / SIMPL
- MSX tR PCM
- Music Module
- Key click
- MSX-Music
- PSG
- Konami SCC
At the end of the document you'll find also some tips to get timing right.
In this document every example plays 8bit unsigned sample located in
#C000-#CFFF at about 8KHz frequency. To load these examples from BASIC,
you can use following program:
10 'LOADER.BAS
20 IF PEEK(&HF677)<>&HD4 THEN POKE &HF677,&HD4:POKE&HD400,0:RUN"LOADER.BAS"
30 BLOAD"COMPILED.BIN",R ' Run initialization code.
40 BLOAD"SAMPLE.DAT" ' Load sample data to #C000-#CFFF
50 A=USR(0) ' Play sample
In MSX tR you can generate the test sample data by writing following line:
CALL PCM REC (@&HC000,&HCFFF,3):SAVE"SAMPLE.DAT",&HC000,&HCFFF
If you don't have tR, then import the data from Amiga, PC, Mac or some
other computer.
Let's start from easy ones...
Covox / SIMPL
-------------
Covox aka SIMPL is easy to build hardware, that is connected to printer port.
Here is routine, that plays sample using this device:
;------------------------------------
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
RET
PLAY:
DI
LD HL,#C000 ;Start address
LD BC,#1000 ;Lenght
PLAYLOOP:
LD A,(HL)
INC HL
OUT (#91),A ;8-bit unsigned data to printer port.
EXX
LD B,60
WAIT: DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
MSX tR PCM output
-----------------
...works same way as Covox/SIMPL so routine above can be used.
OUT (#91),A need to be changed to OUT (#A4),A
Music-Module
------------
Music-Module has 8-bit DAC as well, but it needs to be activated first. Here
is a sample routine for Music-Module:
;------------------------------------
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
INIT:
LD A,#18
OUT (#C0),A
LD A,1
OUT (#C1),A
RET
PLAY:
DI
LD HL,#C000
LD BC,#1000
PLAYLOOP:
LD A,(HL)
INC HL
OUT (#A),A
EXX
LD B,60
WAIT: DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
Key click
---------
Key click was used on many MSX1 games to play samples. As this output is only
1bit wide sound quality is bad. I suggest using PSG instead whenever it is
possible.
Key click bit is located in PPI port C, I/O port #AA/bit 7. However, in this
example we use PPI control register (I/O #AB) instead of writing the bit
manually. By changing the bit from 7 to 5 you can also use this routine to
save the sample as audio to cassette deck.
;------------------------------------
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
RET
PLAY:
DI
LD HL,#C000
LD BC,#1000
PLAYLOOP:
LD A,(HL)
INC HL
ADD A,A
LD A,0
ADC A,14
OUT (#AB),A
EXX
LD B,60
WAIT: DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
MSX-Music
---------
MSX-Music has also 6bit output in each of 9 channels that can be used to play
samples. This is not anyway documented feature. I did some tests and it seems,
that #FF need to be written to OPLL test register #F (No, 9 is not enough) and
channel specific SELECT register (#20-#28) bits 1-4 should be set to 1. Also
#20 should be put to channel specific VOLINS register. (#30-#38) After this
bits 2-7 in LOWFRQ registers (#10-#18) can be used as 6bit digital output.
If you can't hear anything, execute CALL MUSIC first!
Bit 0 of SELECT register seems to be also digital output, but level is not
double compared to LOWFRQ bit7, so it can't be used as 7th bit. Because output
level is not very high, you may want to modify the routine to play on multiple
channels at a same time.
;------------------------------------
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
INIT:
LD HL,#0FFF
CALL WRFM
LD HL,#203F
CALL WRFM
LD HL,#3020
CALL WRFM
RET
WRFM:
LD A,H
OUT (#7C),A
EX (SP),HL
EX (SP),HL
LD A,L
OUT (#7D),A
EX (SP),HL
EX (SP),HL
RET
PLAY:
DI
LD HL,#C000
LD BC,#1000
LD A,#10
OUT (#7C),A
PLAYLOOP:
LD A,(HL)
INC HL
OUT (#7D),A
EXX
LD B,60
WAIT: DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
PSG
---
PSG is available in every MSX, so it is quite a good choice for playing
sample. In PSG sample playing need to be done following way:
Every channel frequency needs to be set to value 0. This causes frequency
generator to be switched off and sound output set to value defined by volume.
Now you can play sample by changing volume. This is anyway a bit problematic
as volume in PSG is not linear but can be calculated from formula: output
level = 2^-((15-volume)/2)
This means that we need to find combinations that cause output level to be as
close as possible to 8bit values. Luckily Arturo Ragozini has already done
these calculations for us, so that we can use ready tables.
;------------------------------------
DEFB #FE
DEFW BEGIN
DEFW END
DEFW START
ORG #D000
BEGIN:
DB 00,01,02,03,04,03,05,03,04,05,06,06,05,06,06,06
DB 06,06,07,06,07,08,08,08,07,07,09,07,09,09,08,08
DB 09,09,08,09,09,09,09,09,10,10,10,10,09,09,10,10
DB 10,10,09,10,11,11,11,11,11,11,11,11,10,10,10,11
DB 11,11,11,11,11,11,11,12,11,11,12,12,11,12,11,12
DB 12,12,12,11,12,11,12,12,12,12,11,12,12,12,12,11
DB 12,13,12,13,11,13,13,13,13,13,13,11,13,13,13,13
DB 13,13,13,12,13,13,13,12,12,13,12,13,13,13,13,13
DB 13,12,13,13,13,13,13,13,13,14,13,13,14,14,14,14
DB 14,14,13,14,14,13,14,14,14,14,14,14,13,14,14,14
DB 14,14,14,13,14,14,13,14,14,13,13,14,14,14,14,14
DB 14,14,14,14,13,14,14,13,14,14,14,14,14,14,13,14
DB 14,14,15,14,15,15,15,15,15,15,15,15,15,15,15,15
DB 14,15,15,15,15,15,15,14,15,15,15,15,15,15,15,15
DB 15,15,15,15,15,15,15,15,15,15,15,14,15,14,14,14
DB 14,14,15,15,14,15,15,14,15,15,15,15,15,15,15,14
DB 00,00,00,00,00,02,00,02,02,03,01,02,04,04,03,04
DB 04,05,04,05,05,02,03,04,06,06,01,06,02,03,06,07
DB 05,06,07,06,06,06,07,06,04,04,05,06,08,07,06,06
DB 07,06,08,07,03,04,03,04,04,05,05,05,08,09,09,07
DB 07,07,08,07,08,08,08,02,08,09,03,05,09,05,08,06
DB 06,07,06,10,07,09,08,07,08,08,09,08,08,09,08,10
DB 09,00,08,01,10,02,03,04,04,05,06,10,06,06,06,07
DB 06,07,07,10,08,08,07,11,11,08,11,08,09,09,09,08
DB 09,11,09,09,10,10,10,10,10,00,10,09,02,02,04,03
DB 04,04,11,05,05,11,07,07,07,07,07,08,10,08,08,08
DB 08,08,09,11,09,09,12,08,09,12,11,09,10,10,09,10
DB 10,10,10,09,11,10,10,12,10,10,11,11,11,10,12,11
DB 11,11,00,11,01,02,03,04,03,04,04,05,05,05,06,07
DB 12,07,07,07,08,07,08,12,08,08,08,09,08,09,09,09
DB 08,09,09,09,09,10,10,09,10,10,10,13,09,13,13,13
DB 13,13,10,11,13,11,10,13,11,11,11,11,11,10,10,12
DB 00,00,00,00,00,00,00,01,01,00,00,00,01,00,02,02
DB 03,02,01,04,01,01,01,01,03,04,00,05,01,01,04,01
DB 01,00,04,02,03,04,01,05,01,02,01,00,02,06,03,04
DB 01,05,06,04,00,00,02,02,03,02,03,04,06,02,03,02
DB 03,04,00,05,02,03,04,00,05,00,02,00,03,02,07,01
DB 02,00,04,00,03,07,00,05,02,03,08,04,05,00,06,07
DB 03,00,07,00,08,01,01,01,02,01,00,09,02,03,04,01
DB 05,03,04,07,01,02,06,01,02,05,04,06,02,03,04,07
DB 05,07,06,06,00,01,02,03,04,00,05,08,00,01,00,02
DB 02,03,00,03,04,03,00,01,02,03,04,00,09,02,03,04
DB 04,05,00,08,02,03,00,07,05,03,09,06,00,01,07,03
DB 04,04,05,08,10,06,06,08,07,07,00,00,01,08,09,04
DB 05,05,00,06,00,00,00,00,02,02,03,02,03,04,03,00
DB 01,02,03,04,00,05,02,06,04,04,05,00,06,02,03,04
DB 07,05,05,06,06,00,01,07,03,04,04,00,08,02,03,04
DB 04,05,07,00,06,01,08,07,04,05,05,06,06,09,09,11
START:
LD HL,PLAY
LD (#F39A),HL
INIT:
LD BC,#5A0
XOR A
INITLOOP:
OUT (C),B
OUT (#A1),A
DJNZ INITLOOP
OUT (C),A
OUT (#A1),A
RET
PLAY:
LD C,#A1
EXX
DI
LD HL,#C000
LD BC,#1000
PLAYLOOP:
LD A,(HL)
INC HL
EXX
LD L,A
LD H,#D0
ld b,(hl)
inc h
ld e,(hl)
inc h
ld h,(hl)
ld a,8
out (#A0),a
inc a
out (c),b
out (#A0),a
out (c),e
inc a
out (#A0),a
out (c),h
LD B,50
WAIT: DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
Konami SCC
----------
In Konami SCC you have theoretically three different methods to play sample.
As SCC plays actually 32 byte 8bit signed samples, first idea would be
updating the sample memory at same speed as SCC plays it. This is anyway very
hard to get right because we can not know where SCC is actually playing and we
can not reset the pointer either. Because of the hard implementation this idea
is skipped.
Second method is to use same kind of volume techniques as we used on PSG
sample playing. In SCC the volume (0-15) is linear, so tables are not needed.
To implement full 8-bit output we need at least 2 samples. One that has full
volume all the time (upper 4bits) and another sample with full volume/16
(lower 4bits). This kind of implementation can be found from example 1.
Because SCC has signed samples, full volume is either up or down from zero
level. To go to both directions, we need 4 samples. This kind of advanced
implementation can be found from example 2. This also gives double volume
compared to 2 sample version.
One important thing to know is that change of volume is not implemented
immediately in SCC. Normally it is changed when next byte from sample memory
is played, but writing value to frequency causes current byte to be started
again. As in this example we write values very quickly to frequency registers
the internal sample counter does not actually move at all.
Third method is a variation of first method. As we don't know where SCC is
playing, let's update the whole sample memory with one and same new value.
To make sample rate not variable in low sample rates we first stop SCC from
reading sample memory. This can be done by writing value less than 9 to
frequency. Now we can update sample RAM so, that output does not change.
After sample RAM has been updated, we start SCC internal counter so that
value (where ever the counter was) is sent to output. This routine can be
found below as example 3.
Please note, that at least at time of writing this document, most (if not all)
of MSX emulators work wrong when it comes to SCC details. This may cause some
minor misbehaviour.
Example1:
;------------------------------------
SLOT: EQU #1 ;SCC Slot ID
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
INIT:
LD A,SLOT
LD H,#80
CALL #24
LD A,#3F ;Move to SCC page
LD (#9000),A
LD HL,#9800
LD DE,#9801
LD BC,#20
LD (HL),128 ;Max volume (=-128) sample
LDIR
LD C,#20
LD (HL),248 ;Max volume / 16 (=-8) sample
LDIR
LD HL,#FFFF ;Set low frequency for both samples
LD (#9880),HL
LD (#9882),HL
LD A,3
LD (#988F),A ;Enable channels 1&2
RET
PLAY:
LD HL,#FFFF
EXX
LD HL,#C000
LD BC,#1000
PLAYLOOP:
LD A,(HL)
INC HL
EXX
LD D,A
RLCA
RLCA
RLCA
RLCA
LD E,A
LD (#988A),DE ;Volume for sample 1&2
LD (#9881),HL ;Update frequency for sample 1&2
LD B,55
WAIT: DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
Example2:
;------------------------------------
SLOT: EQU #1 ;SCC Slot ID
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
INIT:
LD A,SLOT
LD H,#80
CALL #24
LD A,#3F
LD (#9000),A
LD HL,#9800
LD DE,#9801
LD BC,#20
LD A,C
LD (HL),127
LDIR
LD C,A
LD (HL),8
LDIR
LD C,A
LD (HL),128 ;-128
LDIR
LD C,A
LD (HL),248 ;-8
LDIR
LD HL,#FFFF
LD (#9880),HL
LD (#9882),HL
LD (#9884),HL
LD (#9886),HL
LD A,15 ;Enable channels 1-4
LD (#988F),A
RET
PLAY:
DI
LD HL,#C000
LD BC,#1000
PLAYLOOP:
LD A,(HL)
INC HL
EXX
ADD A,A
PUSH AF
LD H,A
RLCA
RLCA
RLCA
RLCA
LD L,A
LD DE,0
POP AF
CALL C,CFLGUP
CALL NC,CFLGDOWN
LD (#988A),HL
LD (#988C),DE
LD HL,#FFFF
LD (#9881),HL
LD (#9883),HL
LD B,44
WAIT DJNZ WAIT
EXX
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
CFLGDOWN: ;HL=DE : DE=-HL
LD A,H
CPL
LD H,A
LD A,L
CPL
LD L,A
INC HL
EX DE,HL
RET
CFLGUP: ;JUST WASTE AS MUCH TIME AS CFLDOWN ROUTINE DOES
LD A,A
LD A,A
LD A,A
LD A,A
EX AF,AF'
INC BC
CPL
SCF
RET
END:
;-------------------------------------------------------------------
Example3:
;------------------------------------
SLOT: EQU #1 ;SCC Slot ID
DEFB #FE
DEFW BEGIN
DEFW END
DEFW BEGIN
ORG #D000
BEGIN:
LD HL,PLAY
LD (#F39A),HL
INIT:
LD A,SLOT
LD H,#80
CALL #24
LD A,#3F
LD (#9000),A
LD HL,0
LD (#9880),HL
LD A,15
LD (#988A),A
LD A,1
LD (#988F),A
RET
PLAY:
DI
LD HL,#9881
LD DE,0C000H
LD BC,1000H
PLAYLOOP:
LD A,(DE)
XOR 128 ; Convert to signed data
INC DE
LD (HL),0 ; Stop output update
EXX
LD HL,9800H
LD DE,9801H
LD (HL),A
LDI ; 32 x LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LDI
LD B,16
WAIT: DJNZ WAIT
EXX
LD (HL),#FF ;Update output
DEC BC
LD A,B
OR C
JP NZ,PLAYLOOP
RET
END:
;-------------------------------------------------------------------
Few words about sample timing...
--------------------------------
All these examples have been timed using CPU. This is ok as long as we work
with non over clocked computers and we don't want to multitask. If this kind
of activity is required then external timer is a good idea. External timer is
also quite a big help when we want to play notes on samples.
Standard MSX1 is worst case scenario as it usually does not have anything that
you could use for sample timing. Only timer available is 50/60Hz VDP
interrupt, that is awfully too slow for sample purposes.
In MSX2 VDP's Horizontal Retrace Flag in status register 2 can be used to get
about 15.6KHz frequency. This can be very useful especially if you are
planning to do VDP tricks at a same time you play sample.
If you are not afraid of extreme tricks you may also use MSX2 real time clock
for sample timing. This means, that you first need to detect/set VDP 50/60HZ
mode. Then make a fast custom interrupt routine that calculates real time
using VDP interrupts. Then you need to synchronize Real-time clock time to
VDP clock and set RTC to test mode by using RTC register #E. This way you
can get 16 KHz timer. After playing sample, you need to restore RTC and
synchronize time back to it as users really don't like to get their clock
messed up!
MSX tR has sample timer located at I/O ports. #E6 & #E7 In MSX tR A1GT you
can use also MIDI interrupts to play sample.
Many external devices like Music-Module, RS-232 interfaces, Disk drive
interfaces, MIDI interfaces etc. have also different kind of timers. If you
require such interface, you might want to use these timers as well. Best
timers can also generate interrupts so, that you can do sample playing at
background.
~NYYRIKKI
| | ro msx guru Berichten: 2329 | Geplaatst: 09 September 2005, 19:42   | nifty !
| | SolidEric msx freak Berichten: 202 | Geplaatst: 09 September 2005, 20:42   | Is it possible to play mod-files on psg/music-module/fmpac or scc? I know it can for moonsound and turbo-r
| | manuel msx guru Berichten: 3447 | Geplaatst: 09 September 2005, 21:32   | he ro, can you send me an e-mail on manuel AT msxnet DOT org?
| | NYYRIKKI msx master Berichten: 1510 | Geplaatst: 09 September 2005, 22:13   | For MOD-files you need MoonSound OR tR. I don't remember the name for MSX2+MoonSound program, but for MSX tR there is MOD-player and MOD-editor made by Xelasoft.
CPU power is not enough to play reasonable sound quality on standard MSX2 without hardware acceleration. I have anyway wrote a MOD-player for MSX1 (that is more like a joke) :
http://www.msx.org/MOD-player-for-MSX1.newspost2174.html
| | SolidEric msx freak Berichten: 202 | Geplaatst: 09 September 2005, 22:42   | And with hardware acceleration you mean 7mhz??
| | norakomi msx professional Berichten: 861 | Geplaatst: 10 September 2005, 00:06   | i read some of the article, very interesting.
So I can actualy play samples using the fm-pac or scc !!!! thats great.
I remember pennant race, by konami, which has some voice in the game.
Is this actualy "playing a sample"??
NYYRIKKI do you have some (real simple) examples (in basic, or assembly)
of how to load a sample (psg, scc, fm-pac, whatever) which I can listen to.
Id like to listen to the quality, and look at the size of those samples.....
| | norakomi msx professional Berichten: 861 | Geplaatst: 10 September 2005, 00:07   | btw, yours IS the biggest forum post ever man !!  | | NYYRIKKI msx master Berichten: 1510 | Geplaatst: 10 September 2005, 10:39   | With hardware acceleration I actually meant device, that can play samples without CPU usage (Like moonsound) I think, that even 7MHz is too slow. MSX tR can mix at 11KHz samplerate and I think that it is the absolute minimun to get any reasonable output.
Quote:
|
NYYRIKKI do you have some (real simple) examples (in basic, or assembly)
of how to load a sample (psg, scc, fm-pac, whatever) which I can listen to.
|
Any file loading routine will do the trick. Important thing is, that the sample data is 8bit unsigned mono data. Here is example, how to make this SAMPLE.DAT file mentioned in documentation with Windows standard tools: (This file can be loaded with BLOAD, see example)
- Select Start/Programs/Accessories/Entertainment/Sound Recorder and record few seconds of something.
- Select Save, and as savetype select PCM: 8kHz ; 8bit ; mono.
- Save the file as SAMPLE.WAV to C:\TEMP
- Select Start/Programs/Accessories/Command prompt
- Type following:
CD C:\TEMP
DEBUG SAMPLE.WAV
E 133 FE 00 C0 FF CF 00 C0
RBX
0
RCX
1007
W 133
Q
REN SAMPLE.WAV SAMPLE.DAT
| | ARTRAG online msx master Berichten: 1686 | Geplaatst: 10 September 2005, 11:23   | @NYYRIKKI
A note on PSG:
Quote:
|
PSG
Now you can play sample by changing volume. This is anyway a bit problematic
as volume in PSG is not linear but can be calculated from formula: output
level = 2^-((15-volume)/2)
|
for volume = 0 the output level is zero
Quote:
|
This means that we need to find combinations that cause output level to be as
close as possible to 8bit values. Luckily Arturo Ragozini has already done
these calculations for us, so that we can use ready tables
|
Grauw has done a lot of work as well and the tables you posted are from his programs.
A note on SCC (!!!!!):
If the level is linear and each channel has 16 levels (0-15), in order to get 8bit quality you cannot
simply combine two channels!!! You need to tack into account the replicate values !!! 1 + 2 = 2 + 1 =3
2 channels give you only 30 levels!!!! (5 bit => 32 levels)
3 channels give you 45 levels!!! (+/- 5.5 bits...)
4 channels give you 60 levels!!! (6 bit => 64 levels)
6 channels give you 90 levels!!! (+/- 6.5 bit ...)
etc etc
I haven't a formula, but I think that in order to get 8 bit quality
you need more than 9 channels playing at the same time !! ! (Not an SCC  )
You routine could be incorrect if you didn't considerd this!
Actually reading better you post, your method IS incorrect.
If you play 4 bit in a channel and 4 bit in a different one,
your output wave is distorted.
| | ARTRAG online msx master Berichten: 1686 | Geplaatst: 10 September 2005, 11:36   | @NYYRIKKI
I am interested to the timing matter on MSX2
I need more details....
Do the HR bit in the VDP work also during in the Vblank and the border tracing?
What is the HR frequency?
What is the RTC on the MSX2, how does it work?? What is its resolution?
| | Edwin msx professional Berichten: 620 | Geplaatst: 10 September 2005, 11:41   | Quote:
| btw, yours IS the biggest forum post ever man !! 
|
Probably also the one with the most MSX related information
Cool to have all this info together though. | | Edwin msx professional Berichten: 620 | Geplaatst: 10 September 2005, 11:48   | Quote:
| I haven't a formula, but I think that in order to get 8 bit linear
quality you need more o less 8 or 9 channels at the same time !!
|
Actually, that'd be 17 channels. (255/15) | | ARTRAG online msx master Berichten: 1686 | Geplaatst: 10 September 2005, 11:59   | OK I was wrong!!
Reading the code I see the ponit.
You have also altered the level of the samples in the two channels!
This allows you to get the full 8 bit range.
sorry
| |
| |
| |