joyrex2001 / castools

This is a set of tools which can read sampled MSX tapes and convert them to the standard .cas format and back to .wav samples. This package consist of three tools: wav2cas, cas2wav and casdir.
GNU General Public License v2.0
38 stars 6 forks source link

openMSX compatibility issues #4

Open oboroc opened 6 years ago

oboroc commented 6 years ago

I did a simple experiment. In openMSX 0.14: 1) booted Yamaha CM5-II/128 configuration; 2) pressed menu key, created new tape image; 3) typed in one line basic program 10 print "lalala"; 4) typed csave, this generated a wav file: CX5MII MSX sub ROM 0001.wav.zip; 5) used your wav2cas tool: wav2cas "CX5MII MSX sub ROM 0001.wav" "CX5MII MSX sub ROM 0001.cas" CX5MII MSX sub ROM 0001.cas.zip

Please note, it should be a very simple cas with a single basic section, but wav2cas generated 11 "custom" sections. Here is the output from casdir.exe "CX5MII MSX sub ROM 0001.cas":

------  custom  000000
------  custom  000010
------  custom  000020
------  custom  000030
------  custom  000040
------  custom  000050
------  custom  000060
------  custom  000070
------  custom  000080
------  custom  000090
------  custom  0000a0

This cas file doesn't load.

joyrex2001 commented 6 years ago

Thanks Adrian.

It seems the problem is in the phasing of the signal, when I phase-shift the signal, the wav is processed correctly; wav2cas -p CX5MII\ MSX\ sub\ ROM\ 0001.wav test.cas will produce the expected file.

Not sure what would if this needs a fix, or what the fix would be. I think there a two options; [1] switch defaults, or [2] try to autodetect phasing (but how)?

oboroc commented 6 years ago

Autodetect would be awesome, but I too don't know how to do it. Right now I don't even know what a phase is.

39ster commented 11 months ago

Hi both,

I've been messing around with Castools recently as I've been expanding my knowledge about the MSX hardware since it was the first computer I had as a child. I've been looking at waveforms samples from cassettes I've captured the audio from myself. I've also captured the audio from a BSAVE from my real Toshiba HX-10 and the audio looks much more like Oboroc wav file he uploaded.

Oboroc shows a waveform which looks more square wave, with the transition between frequency changes at low level signal. My Toshiba is very similar but more saw-tooth shaped, but this could be because I captured the audio from the analogue cassette out which smooths out the hard transitions rather than from an emulator, however the transitions are the same at the signal low level. Castools when generating a WAV from a CAS file has the transition in the middle of the rising edge as it crosses the zero line, I don't think the fact it's sinusoidal shape matters, but if real hardware produces the start of phase at the low level, rather than half way up the edge, it's possibly the best default setting.

Obroc, so in simple terms, phase is to do with waveforms, how they relate to each other and where they start. If you look up online about waveforms and phases, this should teach you what phases are.

I'm not really a C programmer but I understand the code a little.

I changed line 123 in the cas2wav.c file from a sin function to a -cos function to shift the phase 90° to the left to make it start at the low level. This then made a wave output file which looks truer to real hardware.

putc( (char)(**-cos**((double)n*scale)*127)^128, output);

Obviously cassettes and players have aged from the 1980s so waveforms stored on cassettes will be somewhat degraded from the original output signal. From looking at the MSX red book and the ROM BIOS calls, it looks like all the MSX computer does is first detect a header by counting 1111 stable transitions (cycles), then measuring the number of times the CPU runs through a loop for a transition for the next 256 cycles, finding the average of these 256 cycles to work out the average time for the cycle for the high frequency. Then it just counts how many times the signal changes from one state to another once it detects a start bit, to work out if it's a zero or one.

Another feature which may be useful is rather than have a fixed frequency read at the header, is to correct the frequency throughout the read, to account for wow on the playback of the physical cassette, since the stop bits are known, they could be measured to correct any frequency drift, so maybe once the header is found and the frequency determined, the average of the last, say 128 stop bits is used as the reference frequency, it could be done by wrapping a 128 value buffer, so the oldest value is always overwritten and a new average calculated on every start bit read.