Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - High-quality PCM with pcmenc - feedback requested

Reply to topic
Author Message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
High-quality PCM with pcmenc - feedback requested
Post Posted: Fri Mar 11, 2016 9:26 pm
Last edited by Maxim on Mon Jun 24, 2019 10:45 pm; edited 1 time in total
Edit: see source and binaries at https://github.com/maxim-zhao/pcmenc

-------------------

I'm part-way through an experiment with a tool called "pcmenc" from the world of MSX, which does extremely heavy CPU crunching of samples to produce a stream of volume commands with very high signal-to-noise ratio. I'm not quite ready yet, but I have produced the attached rendition of the infamous Cathy Dennis Sega Power cover cassette - or rather, about a minute of it.

It sounds very good in Meka, which is a bit surprising :) but I'd appreciate feedback about how it sounds on real hardware.

This is updating one PSG channel every 1/44100s and the tool reports a SNR of 21.4 if that means anything. There are other modes of operation at lower sampling rates but better accuracy, but I still need to tune the assembly timing a bit...
test.zip (995.26 KB)

  View user's profile Send private message Visit poster's website
  • Joined: 25 Feb 2006
  • Posts: 862
  • Location: Belo Horizonte, MG, Brazil
Reply with quote
Post Posted: Fri Mar 11, 2016 10:44 pm
Sounds great! :)
  View user's profile Send private message Visit poster's website
  • Joined: 18 Dec 2014
  • Posts: 95
  • Location: Canada
Reply with quote
Post Posted: Fri Mar 11, 2016 10:54 pm
Sounds great
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Fri Mar 11, 2016 11:43 pm
Better music, longer (64 bit build needed because it uses a huge amount of RAM to encode), unfortunately the 4MB limit is a bit low for a whole song. I suspect the bank packing is not very efficient, though.
test.zip (2.53 MB)

  View user's profile Send private message Visit poster's website
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Sat Mar 12, 2016 12:31 am
Tested on MD model 1. Sounds great.

Have no way to record it atm :(
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Sat Mar 12, 2016 6:50 am
Awesome, now to fix up the other players. The timing and behaviour of the player code is an input to the encoder, so each sampling rate has a bespoke player, and they need adaptation from the MSX code.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Sat Mar 12, 2016 7:28 am
i should have mentioned. It is very very sort. Had to turn tv to 100% and still soft. Volume typically a problem with PCM on master system?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Sat Mar 12, 2016 8:34 am
It should be as loud as most SMS PCM, i.e. a bit quiet.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Tue Apr 12, 2016 8:58 pm
The code and binaries are up on GitHub:

https://github.com/maxim-zhao/pcmenc/releases/tag/v0.1

Right now it sounds pretty good, but I'd like to do some comparison with high-sampling-rate audio using other techniques (simple volume updates, or blargg's low-frequency DC offsetter) to figure out how much it really makes a difference.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon May 16, 2016 1:42 pm
Maxim wrote
Better music, longer[...]


Is it taking 27KB *per second* or am I wrong with my math? :|
I wonder if I can safely assume a 8KHz audio will use 8/44 of this... which is roughly 4.9KB. Wrong?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Mon May 16, 2016 4:12 pm
The encoder comes with an RLE encoding scheme for PCM, which is a bit weird but good at eating up the silences. However, the overhead often means it has marginal, or negative, gains over raw data, and I didn't write a decoder for raw data yet. If we assume parity, then there's 4 bits per sample at 44kHz so 22KB per second.

At 8kHz the quality of music takes a big hit. For sound effects and voices it's not so bad. Try 16 bit PCM at 8kHz on your PC to prototype, and it's going to end up pretty close to that. However, if you can up the data rate again you will get much better fidelity, by updating more than one channel per sample (referred to as the ratio in pcmenc).
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue May 17, 2016 10:02 am
I thought you were encoding the volumes of the 3 PSG square channels... and quality seems much higher than an uncompressed 4 bit per sample PCM... so I didn't expect to see any 'parity' in size.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Tue May 17, 2016 6:33 pm
You can spend 4, 8 or 12 bits per sample, and the code round-robins the three tone channels as the sample plays. At high sampling rates you can get away with fewer bits because any errors are less perceptible, which is handy because the data rate is so high. The algorithm just brute-forces the choice of bits to minimise the deviation from the input data, although the metric is not at all perceptual, and thus maybe could do better.

The RLE encoding doubles the data size per sample but also encodes runs of up to 16 identical values per channel in a single byte. The overhead of doing this means you can't do the highest bit rate at high sampling rates, because you run out of CPU time.

In practice, I've found that it outperforms pretty much everything else at a given data rate, but the source data seems to be the most important factor - clean audio, with good filtering, resampling, normalisation and range compression makes a lot of difference. If your data rate results in 8kHz at 4 bits per sample, be prepared for sub-telephone-quality audio.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Apr 2011
  • Posts: 250
  • Location: Netherlands
Reply with quote
Post Posted: Wed May 18, 2016 8:20 am
Last edited by Zipper on Wed May 18, 2016 10:13 am; edited 2 times in total
Hi Guys,

There is another tool in the making from the same guy (ARTRAG) who worked on the MSX version of PCMenc.

It's a LoFi sample replayer working on the Vblank interrupt. Very low ROM and CPU usage!

The quality improves when using more channels. Next week we will be experimenting on YM2413. ;)

Here is a WIP video.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed May 18, 2016 8:34 am
Oh, I didn't get I can choose how many channels I want to use. I think I've got to run some test myself to see how good this can get :)
Thanks!
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Wed May 18, 2016 11:32 am
You don't get to choose the channel usage, just the timing of the use of each nibble. The intention is to use all the channels to maximise the available output levels at each sample, then to make a best effort on the quantisation to those levels. Reducing the channel count makes it much harder to get any great accuracy. Some experiments suggests that dumb 1-channel quantisation, and blargg's less dumb DC offsetter, suffer a lot from the lack of quantisation levels.

PRs with more player code are welcome, there's a lot of options but not many players. I was experimenting with a player that could dynamically generate delay loops to match your chosen sampling rate, but that was probably a bit overcomplicated.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Wed May 18, 2016 5:55 pm
Zipper wrote
LoFi sample replayer

It sounds a lot like furrtek's PSGTalk tool, but better. Pretty much unintelligible, though...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed May 18, 2016 8:45 pm
60 Hz update of square waves? It's hard to call that PCM...
  View user's profile Send private message Visit poster's website
  • Joined: 06 Apr 2011
  • Posts: 250
  • Location: Netherlands
Reply with quote
Post Posted: Thu May 19, 2016 9:29 am
Maxim wrote
It sounds a lot like furrtek's PSGTalk tool, but better. Pretty much unintelligible, though...


Thanks. That was the thread I was looking for!
Of course the quality is quite unintelligible. But still interesting as SFX engine for games.

Anyway any other posts I will add to that thread.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu May 19, 2016 11:39 am
Personally I would find that interesting if:
- it implements a WAV -> VGM converter
- it gives the user a chance to set the desired update rate

I imagine this way one could for instance create a 300Hz VGM and play it using PSGlib, simply calling the PSGFrame function 5 times each NTSC frame, or 6 times each PAL frame. Quality won't compare with 'real' PCM, though, but ROM and CPU cost would be very small.
  View user's profile Send private message Visit poster's website
Revo
  • Guest
Reply with quote
Post Posted: Tue Jan 24, 2017 8:46 pm
Is that possible to make pcmenc compatible with win10 ?

Also pcmenc is crashing on my win7 computer (in the beginning when loading the wav file) and I've no idea why...
 
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Wed Jan 25, 2017 2:39 am
It is developed on Windows 10. It is not super compatible with WAV files, try to have a plain format without tags.
  View user's profile Send private message Visit poster's website
Revo
  • Guest
Reply with quote
Post Posted: Wed Jan 25, 2017 3:02 am
This is the message I have when trying pcmenc on my win10 (translated from french):

This version of c:\pcmenc.exe is not compatible with the currently executed version of Windows. Check the system information of your computer and contact the editor of the software.



edit: by ''plain format without tags'' do you mean without extension? If yes, still crashing...
 
  • Joined: 04 Jul 2010
  • Posts: 539
  • Location: Angers, France
Reply with quote
Post Posted: Wed Jan 25, 2017 10:42 am
Windows message seems to be 64bits related.

plain format w/o tags is a simple wav without any metatags/metadatas within it.

I've compiled pcmenc for mac and it's working perfectly with wav. (exported with audacity).
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Wed Jan 25, 2017 11:56 pm
I always use Audacity to export and skip the metadata bit. 64 bits is required, memory usage is insane. I didn't know there was a 32 bit version of Windows 10.
  View user's profile Send private message Visit poster's website
Revo
  • Guest
Reply with quote
Post Posted: Fri Jan 27, 2017 6:37 am
pcmenc is still crashing when using a wav file exported with Audacity (exported as WAV (Microsoft) signed 16-bits PCM), I also deleted metadatas by clicking delete before OK when exporting song.
 
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Sat Jan 28, 2017 12:59 am
I can have a look when I get back to a computer, I'm on holiday now. I usually use 8 bit wavs, but it should work anyway.
  View user's profile Send private message Visit poster's website
Revo
  • Guest
Reply with quote
Post Posted: Sat Jan 28, 2017 7:08 am
Same problem with 8bit wav (in Audacity you have to select ''other uncompressed file'' then 8bit wav (Microsoft)).
 
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Tue Jun 05, 2018 11:10 pm
So I've been working on pcmenc a bit recently and I noticed a terrible bug which meant the maximum output was always 1/3 of what was possible. I've just committed a fix for this - the file history suggests it was broken in the source I started with.

(Technical detail: the code builds a table of volumes achieved for all possible PSG attenuation states. This is built from a normalised 0.0..1.0 volume curve, so the combined maximum is 3.0. It then picked optimum values to map the input data onto this - but the input data is normalised to 0.0..1.0, so it expertly mapped it to a fraction of the available range.)
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Fri Jun 21, 2019 11:03 am
I've been working on including a couple of Samples in Gotris . Although I'm quite newbie using assembler, I've more or less managed to interface from C and adapt the assembler from WLA-DX syntax to ASz80 one. However, when I try I only get som random noises. Someone more proeficient than me with z80 asm can spot any silly error in my approach?

Original Maxim code:

; Get block count
  ld b,(hl)
  inc hl
 
-:; PLay a block (from hl)
  push bc
    call PLAY_SAMPLE
  pop bc
  ; Switch to the next bank
  ld hl,$ffff
  inc (hl)
  ld hl,$8000
  ; And repeat
  djnz -
  ret

; Plays one sample
; hl: pointer to triplet count followed by data
PLAY_SAMPLE:
  ld a,(hl)
  ld ixl,a
  inc hl
  ld a,(hl)
  ld ixh,a
  inc hl
 
  ld c,$7f
 
-:
  ; Starting on a byte boundary version
  rld       ; 18
  and $f    ;  7
  or $90    ;  7
  ld d,a    ;  4

  ld a,(hl) ;  7
  and $f    ;  7
  or $b0    ;  7
  ld e,a    ;  4

  call Delay276

  inc hl    ;  6
  rld       ; 18
  and $f    ;  7
  or $d0    ;  7
 
  out (c),d ; 12
  out (c),e ; 12
  out (c),a ; 12
 
  ; Check counter
  dec ix    ; 10
  ld a,ixh  ;  8?
  or ixl    ;  8?
  ret z     ;  5
 
  ; Starting on a half-byte boundary version
  ld a,(hl) ;  7
  and $f    ;  7
  or $90    ;  7
  ld d,a    ;  4

  inc hl    ;  6
  rld       ; 18
  and $f    ;  7
  or $b0    ;  7
  ld e,a    ;  4
 
  call Delay286
 
  ld a,(hl) ;  7
  and $f    ;  7
  or $d0    ;  7
  inc hl    ;  6
 
  out (c),d ; 12
  out (c),e ; 12
  out (c),a ; 12

  ; Check counter
  dec ix    ; 10
  ld a,ixh  ;  8?
  or ixl    ;  8?
  jp nz,-   ; 10
  ret
 
Delay286:
  jp Delay276 ; 10
Delay276:
  ld b,14     ;  7
-:or a        ;  4*14
  djnz -      ; 13*14-5
  ld a,i      ;  9
  ret         ; 27 (including call)


My approach:

#include "fxsample.h"

void PlaySample (void *sample) __naked {
/* ********************************************************************
 Plays a Sample
*/
__asm   
;Pcmenc Replayer

;load sample
    ld iy,#0x02
    add iy,sp
    ld l,(iy)   ;sample (low)
    ld h,1(iy)   ;sample (high)
    ld b, (hl)
    inc hl
BLOCK_LOOP:
    push bc   
      call PLAY_SAMPLE
    pop bc
    djnz BLOCK_LOOP
    ret

; Plays one sample
; hl: pointer to triplet count followed by data
PLAY_SAMPLE:
  ld a, (hl)
  ld c, a
  inc hl
  ld a, (hl)
  ld b, a
  ld iy,#0
  add iy,bc
  inc hl
 
  ld c,#0x7f
 
BYTE_LOOP:
  ; Starting on a byte boundary version
  rld       ; 18
  and #0x0f    ;  7
  or #0x90    ;  7
  ld d,a    ;  4

  ld a,(hl) ;  7
  and #0x0f    ;  7
  or #0xb0    ;  7
  ld e,a    ;  4

  call Delay276

  inc hl    ;  6
  rld       ; 18
  and #0x0f    ;  7
  or #0xd0    ;  7
 
  out (c),d ; 12
  out (c),e ; 12
  out (c),a ; 12
 
  ; Check counter
  dec iy    ; 10
  ld a,1 (iy)  ;  8?
  or 0 (iy)    ;  8? TODO REVISAR
  ret z     ;  5
 
  ; Starting on a half-byte boundary version
  ld a,(hl) ;  7
  and #0x0f    ;  7
  or #0x90    ;  7
  ld d,a    ;  4

  inc hl    ;  6
  rld       ; 18
  and #0x0f    ;  7
  or #0xb0    ;  7
  ld e,a    ;  4
 
  call Delay286
 
  ld a,(hl) ;  7
  and #0x0f    ;  7
  or #0xd0    ;  7
  inc hl    ;  6
 
  out (c),d ; 12
  out (c),e ; 12
  out (c),a ; 12

  ; Check counter
  dec iy    ; 10
  ld a,1 (iy)  ;  8?
  or 0 (iy)    ;  8?
  jp nz,BYTE_LOOP   ; 10
  ret
 
Delay286:
  jp Delay276 ; 10
Delay276:
  ld b,#0x14     ;  7
DELAY_LOOP:
  or a        ;  4*14
  djnz DELAY_LOOP      ; 13*14-5
  ld a,i      ;  9
  ret         ; 27 (including call)
__endasm;
}
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jun 21, 2019 1:42 pm
what's the sample file format? it seems it has at least a one-byte header (block count) and after that simply maps everything following first block at $8000...

did you account for that? or are you playing a single 16 KB block?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Fri Jun 21, 2019 2:28 pm
The pcmenc "ROM" format is a leading word which is a triplet count (related to the sample count) followed by the raw data. This is then repeated for multiple chunks according to the limit specified.

I don't think the bank count byte is there by default.

Can you specify what format option you are using for the data? How confident are you that the correct data is being mapped?
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Fri Jun 21, 2019 4:21 pm
I used the following options:

pcmenc.exe -rto 1 -p 4 -dt1 12 -dt2 12 -dt3 423

I don't know if the number of chunks is included by default, I was following the example of Space Harrier. I'll attach the encoded file, just in case... (and my source file)
fxsample.c (1.78 KB)
sample-data.txt (53.75 KB)

  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Fri Jun 21, 2019 6:19 pm
I do funky stuff in those sample hacks, better to go off the pcmenc repo. If your data is bigger than 16KB then it's more tricky to deal with.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Sat Jun 22, 2019 12:51 pm
The sample is just around 7 kb....

There's any place where I can get a reference about how to use pcmenc properly?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Sat Jun 22, 2019 1:59 pm
The replayers are designed to play a single chunk each time they're invoked. Just point at the data and it should work. They also explain in the comments the correct parameters for encoding.

I don't have experience interfacing from C to know more about how to achieve that. The replayers may use registers that are off limits, for example.

Playing back more than 16KB is a matter of playing multiple chunks, but how you do that is up to you. I think you will need some custom program to split things up.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Jun 22, 2019 2:18 pm
Maxim wrote
I don't have experience interfacing from C to know more about how to achieve that. The replayers may use registers that are off limits, for example.


If you don't mess with IX and you don't mess with SP you've got no real problems, and it seems to me he's reading the pointer from stack into HL correctly, even if I would instead simply have declared the function as

void PlaySample (void *sample) __naked __z88dk_fastcall


so that HL would be already pointing to sample...
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Sat Jun 22, 2019 2:21 pm
sverx wrote
Maxim wrote
I don't have experience interfacing from C to know more about how to achieve that. The replayers may use registers that are off limits, for example.


If you don't mess with IX and you don't mess with SP you've got no real problems, and it seems to me he's reading the pointer from stack into HL correctly, even if I would instead simply have declared the function as

void PlaySample (void *sample) __naked __z88dk_fastcall


so that HL would be already pointing to sample...


Uo! I'm quite new to interfacing from C to Asm, but I will use the fastcall thing!. I'll just try to debug with emulicious, for my first impression, everything was working "well"...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Jun 23, 2019 1:05 pm
I would place your own code and Maxim's original one side by side - you should be able to compare line by line and see what's wrong as each single instruction shouldn't have changed at all (apart from the IX to IY replacement of course)
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Sun Jun 23, 2019 4:50 pm
They're equivalent, apart of label names (asz80 doesn't like anonymous lables), how numerals are defined, and specially, how the access to ixh and ixl are done (I've to use (ix+0) and (ix+1)). Funny thing is that I cannot find good documentation of asmz80 anywhere.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Sun Jun 23, 2019 5:41 pm
I think ixl and ixh are not the same as (ix+0) and (ix+1) in any assembler dialect. It's an undocumented opcode but a fairly commonly used one - you can encode it as hex if necessary. The effect ought to be that it plays the wrong number of samples - going on past the end of data, unless ix points to zeroes in memory when it would instead play nothing.

If you can give me some easy to build code then I can try to debug it. What sample rate are you aiming for?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3731
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Jun 24, 2019 9:47 am
IYH and IYL are the upper and the lower part of register IY, not the memory location pointed by (iy+0) and (iy+1).
And unfortunately sdas really have no support for those 'unsupported' opcodes so you should check their hex equivalent here and create some define for the missing ones such as

#define LDIYHA   .db 0xFD 0x67


for ld iyh,a for instance.

Yeah, it sucks totally.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Mon Jun 24, 2019 2:29 pm
Maxim wrote
I think ixl and ixh are not the same as (ix+0) and (ix+1) in any assembler dialect. It's an undocumented opcode but a fairly commonly used one - you can encode it as hex if necessary. The effect ought to be that it plays the wrong number of samples - going on past the end of data, unless ix points to zeroes in memory when it would instead play nothing.

If you can give me some easy to build code then I can try to debug it. What sample rate are you aiming for?


I was emulating your Space Harrier approach, so the sample was 8khz encoded, I used "pcmenc.exe -rto 1 -p 4 -dt1 12 -dt2 12 -dt3 423 sample.wav" to encode it, and I was using this player code: https://github.com/maxim-zhao/sms-hq-samples/blob/master/Common/replayer_core_p4_rto3_8kHz.asm

In any case, I can share you the code, It can be compiled if you have SDCC installes, just executing compile.bat

@sverx: I'll try your approach!
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Mon Jun 24, 2019 3:53 pm
Or you can do
.db $fd ; HL -> IY for next instruction
ld h,a

... If that's any less confusing :)

8kHz is a bit rubbish - I used that because the original arcade samples are that quality. I'd recommend 22kHz or higher if you want it to sound great - depending on the source material. But then you may need bigger sample blocks, and that means some fun splitting data into 16KB chunks.

Better to look at the players here: https://github.com/maxim-zhao/pcmenc/tree/master/players/sms which is where I keep them up to date. Some are in a bit of a state of change (since last year...) due to some confusions about cycle counts between sources (and in Meka). Maybe I can rewrite them to avoid the undocumented opcodes to help avoid that.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Wed Jun 26, 2019 8:07 am
I've defined the unsuported opcodes as:

#define LDIYHA   .dw #0xFD67
#define LDIYLA   .dw #0xFD6F
#define LDAIYH   .dw #0xFD7C
#define LDAIYL   .dw #0xFD7D
#define ORIYL   .dw #0xFDB5


And I use them as:

  ld a, (hl)
  inc hl
  LDIYLA
  ld a, (hl)
  inc hl
  LDIYHA


It assembles, but it doesn't seems to work, and If i try to debug with Emulicious, I see the raw Hex values instead of asm operands...
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14652
  • Location: London
Reply with quote
Post Posted: Wed Jun 26, 2019 9:06 am
The dw words are stored little endian so they end up the wrong way around.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Wed Jun 26, 2019 9:14 am
that sounds like a problem '-_-
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Wed Jun 26, 2019 12:36 pm
I corrected my error, but it's still not working...Only get some random noise.

I'll upload the current WIP rom, just if someone has some inspiration:

EDIT: Btw, sample should sound after the Get Ready title when starting a game.
gotris.zip (33.35 KB)

  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
Post Posted: Mon Jul 08, 2019 1:29 pm
Thanks to Maxim (that debugged my ROM) and Calindro (who let me test his new Emulicious version) I've been able to include the samples in my version of Gotris. They're currently only placeholders until I get the new ones, but I'm attaching the rom here just if someone wants to hear how they sound (they're played when starting a game, and in the game over).

I'm not updating the homebrew entry for Gotris because some additional assets are still placeholders (like the high score screen and its music) but you can find lot of improvements in playability annd other minor tweaks from the version submited to the compo:
gotris.zip (44.1 KB)

  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 878
  • Location: Spain
Reply with quote
C wrapper for sample playback library
Post Posted: Sun Aug 02, 2020 3:25 pm
The other day one user, MrBurrito, asked me about the wrapper that I did for Gotris, and I realized that I didn't share it anywhere, so I just fixed that:

https://github.com/kusfo/sms-fxsample

Acknowledgments to Maxim for doing the original code, MrBurrito for the example project, Sverx for his work on devKitSMS and Calindro for the magnificent Sega Master System emulator Emulicious.
  View user's profile Send private message
Reply to topic



Back to the top of this page

Back to SMS Power!