fruit-bat / pico-zxspectrum

ZX Spectrum for Raspberry Pico Pi RP2040
475 stars 52 forks source link

Audio input suggestion #46

Open badrianiulian opened 2 years ago

badrianiulian commented 2 years ago

Since I figure that the ultimate goal is to recreate all functionality of the original ZX Spectrum, I am thinking that by using some modified hardware (or some new one even) from this microphone library, this goal can be achieved. By adding a 100uF for isolation purposes as the guidelines for the analog module say maybe we can reach the goal. I may be able (and willing) to test some hardware... I'm no audiophile but I got the tools to make what I usually need so that the analog "Line In" function can be available for the old cassette players out there... maybe even a save to ".tap" directly to the SD Card at the end... for comparison purposes since I still remember how error prone was this process in the old days. I can try some different ways with the hardware part (will research more this part so we don't fry the pico) but since all this work is your baby, only you know if the analog part of the library can be adjusted to work with all the different layouts and if one input pin is available.

fruit-bat commented 2 years ago

This may be of interest : http://www.zxdesign.info/cassette.shtml

Might be fun to be able to load from a real audio source 🙂.

The software side will be tricky. There are moments when the z80 is paused to read the keyboard etc. It catches up afterwards but any audio input will need to be kept in sync.... I think it will require the CPU speed moderation to be rewritten and based on the depth of an audio queue.

badrianiulian commented 2 years ago

From the above, I extracted this: Screenshot_20220813-075606_Drive As for the loading part, how about adding an Cassette mode - F2 key is free - that sets the CPU to 3,5MHz and monitors only the F2 key... just a thought...

fruit-bat commented 2 years ago

I'm not 100% sure but I think Vcc in their design is 5v... So we need to adjust R42 & R41 so that the gate bias is correct for 3.3v. Also, the author says his audio signal goes from -2.3 to +2.6 which seems high to me, I would expect more like -1.1 to +1.1v. The threshold voltage on the pico is about 1.8 volts, rather than 3.7 for the 74hc gate.

fruit-bat commented 2 years ago

Hmm, also this circuit has no gain, which we may want a little of if I am right about the voltage range on the input pin... May need to give this a little thought. If you can take some measurements of actual voltage ranges into a 1k load that would really help. E.g a pc audio jack, a phone, an old tape player.

fruit-bat commented 2 years ago

...Maybe the higher voltage is to able to drive headphones?

fruit-bat commented 2 years ago

On the pico...

"Normally the voltage threshold is about 1.8V, but it isn't guaranteed; it can be anywhere between the maximum input low and minimum input high, that is, between about 0.8 and 2.0V."

fruit-bat commented 2 years ago

Could just try it with 39k for R42. Please correct my junior school maths if I have got it wrong.

Centre voltage... (2.0v - 0.8v) / 2 + 0.8v = 1.4v

Add in the BE voltage... 1.4v + 0.6v = 2v

So... 2 = 3.3 R42 / (R42 + 27) => R42 ~ 40kohm

And pick one that is easy to buy... 39kohms!

badrianiulian commented 2 years ago

Been on the road all day and will be the same for the next two days... we had a planned family trip. As soon as I'll be home, I can take some measurements with actual components and different audio signals.

fruit-bat commented 2 years ago

I hope you have a nice time with your family.

badrianiulian commented 2 years ago

Thank you! I had a nice time with the family ^_^ As for the tests, today I did some measurements and here they are: I set volume to max from PC and had playing sound from Fuse (game menu - ADayInTheLife 1985 - has some really loud sounds):

fruit-bat commented 2 years ago

Thanks for those measurements. It looks like the voltage swing is not really big enough 🙁. It's a shame the adc doesn't work, it would be ideal for this. Maybe we need an amplifier (rather than an emitter-follower) or a Schmitt trigger? Don't want it to get too complicated but I've seen some 2 transistor designs for a Schmitt trigger.

badrianiulian commented 2 years ago

At first glance, an amplifier may be too much (on the other hand it's late and I might not have all the marbles in place right now). I did found some explained details about a Schmitt trigger here and also here. Now regarding the details, we could learn from some actual builds, as this was another find. What should the actual voltage swing need to be? Also as I seem to understand from an alternative design there might be also a need to invert or non-invert the signal... (?)

fruit-bat commented 2 years ago

Well, if the 0.8 to 2.0 volts thing is correct, at least 1.2v.I I don't think it matters if it is inverting or not. Thanks for the links I will read through them when I get a mo.

fruit-bat commented 2 years ago

I've done some more reading and found the rp2040 inputs have their own hysteresis...

https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__gpio.html#ga1f52eecc12d4348ef8bd1e17bdb4b107

I probably need to find out more about that.

badrianiulian commented 2 years ago

I found an example with hysteresis experimentation on the raspberry pi forums. Unfortunately I don't have an oscilloscope to play with. If it takes too much of the CPU though, the hardware way is the way to go.

fruit-bat commented 2 years ago

Been reading this... https://en.m.wikipedia.org/wiki/Line_level ... which suggests 10k (rather than the 1k) load resistance. Perhaps that would give a bit more of a voltage swing.

badrianiulian commented 2 years ago

As I should have expected, when using the 10K, with the PC headphone source (it was the only test I did), the AC voltage is the only difference encountered:

10k resistor = maximum of 65mV AC and 7mV DC
output voltage ~= 1,5V DC

Also the same AC voltage seems to be present at the output line (same as before witch I failed to mention above)... so this is definitely not the way to go. I'll try to find components for the Schmitt trigger schematic... something equivalent to what the 74C/HC14 does.

fruit-bat commented 2 years ago

They are easy to make with an op amp. I've ordered some that will run at 3v to have a play with. We can compare notes then 🙂. I'll post the circuit when I get a mo.

fruit-bat commented 2 years ago

This site is good...

https://www.random-science-tools.com/electronics/inverting-schmitt-trigger-calculator.htm

fruit-bat commented 2 years ago

Something like this...

circuit (1)

The pot is there to adjust the threshold, which we could fix if we find a good value. I'm not sure about the lm224n, just need something that will work at 3.3v.

fruit-bat commented 2 years ago

...but it does turn out the op-amps I have ordered are going to take a long time to get to me!

badrianiulian commented 2 years ago

I dug and found some schematics from different clones of the ZX: HC-2000 Screenshot 2022-08-20 at 17 10 35 CIP-01 Screenshot 2022-08-20 at 17 12 23 After that I changed the testing procedure: I set volume to max from PC and had playing sound from PlayTZX inside DosBox (same game - ADayInTheLife 1985): With the first schematic (transistors) the test had the same result as before. For the op-amp schematic, I used a βM358N instead of a LM224N and also changed the 10k+100kVR to 100k+100kVR(with the actual value set at about 150k). Results:

fruit-bat commented 2 years ago

Hi, sorry for the slow reply, 'real-life' has been distracting me!

The 1st circuit looks like a non-inverting comparator, without hysteresis. I like the way the bias is arranged; the single (rather than dual) voltage divider means you don't have worry about tolerance on the resistor values.

The 2nd circuit looks like a high gain inverting amp... but I'm not sure what R30, R70, D9 & D10 are up to! Do you know what VMED gets connected to?

badrianiulian commented 2 years ago

I know what you mean about 'real life'. I've been pinned to the bed for the last two days due to a nasty cold... better now. I changed the above labels for the schematics since I mislabeled them. I only just noticed by searching through the schematic for VMED witch goes through at least three pages (pages 2,3 and 4). There are other schematics on that site that could prove to be useful.

fruit-bat commented 2 years ago

Thanks for finding those... I will get back to this at some point!

fruit-bat commented 2 years ago

I've added a little test program which reads GP11 at 44Khz and sends 1s and 0s to the USB uart. Not as good as a dual-channel scope but it's something!

cp uf2/ear_in_test.uf2 /media/pi/RPI-RP2/
tio /dev/ttyACM0 
fruit-bat commented 2 years ago

See https://github.com/fruit-bat/pico-zxspectrum/pull/54/files

There is even a small chance this may work! It samples GP11 once a microsecond using the PIO and feeds it into the emulator. Should cope with 32x32 microsecond delay in instruction emulation.

I'ts going to take a bit of work to fix all of the targets so only ZxSpectrumBreadboardHdmi4PinAudio is working at the moment. Let me know if you want a binary to play with.

badrianiulian commented 2 years ago

Been a bit busy digging the net for anything Spectrum for a while now (I lost at least four hours tonight just to find this in the end). Also I've been checking some wav dumps of some tapes since I'll surely need them to test the audio input. I will have to put together another Pico and test it with the breadboard since it's easier in the long run (I ordered a while back one piece of Wren's module and a micro sd card module). For now I'm off to bed (huge headache) but a binary and some instructions to test in a couple of days would be nice. As soon as I can test it (using the components with βM358N), I'll be back with feedback. By the way... when I tested the op amp circuit, I used 3.3V. Since the 3.3V has to be stable for the SD Card, maybe I should test the circuit beforehand using 5V from VSYS just like I used for the HXJ8002 amplifier circuit?

fruit-bat commented 2 years ago

Hope your headache is better. Stick to 3.3v on the opamp. I think 5v will damage the pico.

fruit-bat commented 2 years ago

I've just loaded Frogger from a WAV file 🙂 The circuit I used is a mess but it proves that the software sort of works!!!

fruit-bat commented 2 years ago

Inspired by the HC-2000 diagram you posted above, I think this may be interesting.... circuit It's sort of a schmitt trigger (+/- 100mv ?) but with the nice single voltage divider. What do you think?

Smaller capacitor might work too... maybe 1uF. For +/- 50mV swap the 50k resistor for 100k.

fruit-bat commented 2 years ago

Test binary available: https://github.com/fruit-bat/pico-zxspectrum/blob/feature/audio-in/uf2/ZxSpectrumBreadboardHdmi4PinAudio.uf2

badrianiulian commented 2 years ago

I've been divided in many areas the last couple of days... I'll try to get my tools to work tomorrow (maybe I can squeeze in some build time on this project). The schematic looks good but the ultimate tests will be the wav files. For now tapes are a no go until I can find a working tape player... I do think I recall stumbling on a WalkMan in the basement at some point in the last couple of years.

badrianiulian commented 2 years ago

Hello! I finally tested the new setup and here are the results: 20220907_105406 20220907_111047 20220907_115356

I used the last schematic with the βM358N and changed the 50K resistor to 100K (higher value was better in the earlier test). I tried with 1uF capacitor but had some problems with one of the wav files - it had lots of static noises and gave an R Type error at some point. I used an 4.7uF after but I ended up with the 10uF like in the schematic and the static noises were still there but lowered and the game was loaded. As I said in the earlier tests, sound volume must be above 50 for optimal results (from PC signal).

20220907_105739

I think I must open a new issue though since I encountered a problem: with some games, the (default) keys were not working. They work fine in Fuse though. Both games that had this issue were structured like this:

Main menu game 1 and 2 = press any key to start witch worked just fine.
In-game 1 = 'q,a,o,p,m' keys were not working
In-game 2 = 'left shift,z,c' and '8,9,0' keys were not working while only 'q' key was working ('q' returns to Main menu)
fruit-bat commented 2 years ago

Fantastic news it actually works 😀

If you think the pc volume needs to be too high for a signal to get to the Spectrum you could raise the feedback resistor to 150k (~ +/-30 mv). Don't want to make it too sensitive as the output will start flapping about when there is no input signal.

If you can give me enough information to reproduce the keyboard problem I will try and fix it. Separate issues would probably be best.

Many thanks for the testing and feedback; lovely to see some pictures of it in action.

fruit-bat commented 2 years ago

On the off chance it fixes the keyboard problem I have 'improved' the port decoding and uploaded a new binary. https://github.com/fruit-bat/pico-zxspectrum/blob/feature/audio-in/uf2/ZxSpectrumBreadboardHdmi4PinAudio.uf2

badrianiulian commented 2 years ago

I tested the new binary but I had the same result. I have a feeling that it's not a port decoding issue since in other games those keys work as they should. The setup is through an usb hub but I really do not think that this could be an issue. I don't have an PS2 port attached though... maybe that would help to test the setup.

These are the games that have those issues: Distrugator 1 and Terroindronzon. There is a small save button on each page witch downloads a zipped tzx file. In order to load them as tap files, I converted them using Win_TZX2TAPv0.21.zip. I used the original WAV dumps to load them with the audio input but the tap loading has the same result (as it should).

Maybe debugging these could help in finding the bug.

badrianiulian commented 2 years ago

So I decided to do some more digging today. I removed the USB hub and changed at least three different keyboards. Using some quick saves that had the keys working some builds ago, I tested with an USB-OTG adapter directly connected and the in-game keys do not work anymore. So it may not be about an actual game that it's not working and you may be right about the port decoding issue.

On the other hand, can the tape menu be updated with an ON/OFF switch for GPIO11 (external input/SD card input)? The audio in is active constantly when loading tapes from SD card witch may interfere with the current loading process. I had one R-Type loading error while re-loading a .tap file (that worked before) with all the OP-Amp setup still connected and that shouldn't have happened. After this happened, I reloaded the .tap and it loaded corectly... Interference from GPIO11 could destabilize the loading process.

fruit-bat commented 2 years ago

Thanks for that, and to add to the mystery, game 1 works if I force bit 6 low on a read of port 254 (i.e. 0xbf for no keys pressed).

fruit-bat commented 2 years ago

Hmm, I think there may be more than one issue in all of this.

There is a new uf2 with some code that should sort out the two games with stuck keys... but only as long as the ear input is 'quiet'. Hopefully the hysteresis on the op-amp circuit should mean it is(?).

The tap loader should override the ear input so I'm not sure what is causing that problem. I need to investigate that a little more.

fruit-bat commented 2 years ago

My op amps have finally turned up :-) So now I have to admit which values I guessed incorrectly!

Using my phone to supply the audio I needed a much larger feedback resistor: circuit (1)

The 1uf capacitor worked fine for me (but I know you were having problems).

With standard spectrum tapes this seems to work very reliably... with turbo loaders no so. May need to look in more detail at memory cycle timing... I really never expected the emulator to be doing timing critical stuff!

badrianiulian commented 2 years ago

I was just about to reply after intensive tests using the last build (I was in front of the screen wen you posted the build and got notified instantly) and then I saw your last post about the resistor. The keyboard problem is gone now with those games. I replaced the 100K with 1M but haven't gotten at the point of testing the audio loading from the wavs since I was already testing some other issue by hitting my head against the wall and expecting different results. I restarted testing... for now just like I did in the last couple of hours by loading a tap from the SD Card. Before and now, by loading the same game over and over again I got weird results that I think have to do with me messing with the CPU speed. So here's what I noticed:

  1. F12/128k mode resets automatically to 4.0MHz (it should be 3.54690 MHz, but that could be another issue or maybe not)
  2. F11/48k mode resets to 3.5MHz.
  3. F12/128K mode resets to 4MHz and while in this mode, from the menu you can select 48k mode but the CPU frequency setting remains at 4MHz.

Hitting that tap file over and over again, here is what i found:

At some point (before I saw your last post about the resistor), I had a quick save in the 11th slot that when pressing Alt/F11 showed up only to reset to Basic... it may be related to the above tamperings, to a bad save to the SD Card, to a connection to the F11/48k reset (I doubt it) or to cosmic rays :). It hasn't happened since I've overwritten the quick save with another state.

Also, about what I said earlier about a menu setting about GPIO11 On/Off switch, I found an even more elegant solution:

Another thing: By pressing F1, the system menu shows up but the fields are outdated if a quick save was just loaded. Only by pressing up/down keys and moving through the options, the quick save states are refreshed in the menu options.

I'll get back about the wav loading using different setups (TV/PC/Phone) tomorrow... it's 02.30 and I burned the midnight oil enough for now. (I do enjoy these tests though)

fruit-bat commented 2 years ago

Many thanks for all the detail above. I will go through it in detail shortly. The guidance as to what is an isn't working is very helpful :-)

The default CPU speed settings make much less sense now as loading from tape needs 3.5Mhz (loading .tap from the SD cards should be unaffected as it counts Z80 T states). The reason the 128k defaults to 4Mhz is the VGA 60Hz refresh rate... it probably makes more sense now to default everything to 3.5Mhz and offer an option to change it. The original idea was the 4Mhz CPU would compensate for the faster screen refresh rate.

badrianiulian commented 2 years ago

Got a chance to test things today: Working setup is with the 10uF capacitor and 1MΩ for the feedback resistor. I did found in the schematic of the HC-85 a 2MΩ feedback resistor: Screenshot 2022-09-11 at 17 45 17

As for the actual signal when using the wav files I have, the audio cable needs to be high quality and the connections have to be very tight on each component of the schematic or else the signal will be disturbed by static at some point. I think that the 10uF capacitor helps with the wav files since they seem to be dumped from the tape directly and I recall that a direct copy of a tape had issues back in the days (degradation built-in design of tapes for copy prevention) and that's why copying software was used to transfer programs in memory, only to record them on another tape (clean signal). I checked only with the PC signal since I need a mic/headphones splitter for the phone (I do recall I made at least two of those at some point and one is surely at work). As soon as I'll find one, I'll test again using the phone.

Loading from a tzx file (with playtzx) always works when tested. I even tested a nasty piece of tzx (with built in pulse signals witch prevents converting the tzx to tap) that worked when loaded with playtzx.

All the tests were done in 48k mode (with 3.5MHz).

P.S.: On this page there is the tap file that was used in the previous tests (the head banging against the wall till I found that pattern).

fruit-bat commented 2 years ago

This seems to be much more stable, although I don't really understand why (sorry)...

circuit (2)

fruit-bat commented 2 years ago

New binary available which always defaults to 3.5Mhz and refreshes the menu when F1 is pressed.

badrianiulian commented 2 years ago

Started testing that tap file with the new binary and all loading works as it should now:

Also tested quick save slots: they always load using 3.5MHz regardless of what their save state witch is OK. If anyone needs faster speed they can change it from the F1 menu.

Still haven't found the handsfree audio splitter to test loading tapes using phone signal... Searched at work for now but I'll have to dig deeper into my stash at home. Meanwhile tested with a laptop using the wav files and the most stubborn wav (degraded) loaded only by setting volume to 75% from system sound settings. I left the the 10uF capacitor and 1MΩ for the feedback resistor in place since they have their role in the circuit. The ultimate test will definitely be loading using the phone. I did found some PlayTZX equivalent app for android and noticed that it's setup as default to turn volume up to 75% as an optimal setting.

badrianiulian commented 2 years ago

Success: The splitter I have is actually for the headset side so I can insert mic and headphones to a PC/Laptop(older models) so I ended up buying one splitter (had the parts to make one but do not have the actual time to build it - I do my work usually during the night when the kids are asleep).

I tested playing some tzx file with default app settings (PlayZX app on android phone) witch worked perfectly. The app does output some noise right when finishing a segment and entering a pause but that hasn't influenced tape loading.

Then I went on to test the wav files. At first I got an R-Type error and rechecked my phone settings... volume was too low. I changed the volume level to 12 out of 15 (80%) and after that tested with three different wav files. From then on everything went fine and no errors were encountered.

fruit-bat commented 2 years ago

Many thanks for the update, things look like they are heading in the right direction.

I have spent some time this evening messing about with the input circuit... trying to get a nice balance between enough gain and not too much noise. I have a version that is better but need to have a bit more of a play with it before I bother you with more circuits! The new version has two stages an amp and then a Schmitt-trigger. I'll post a diagram if gets good enough!

Thanks again for the testing and feedback.

badrianiulian commented 2 years ago

Well, as I said earlier, I enjoy these tests so it's not a bother. I listened to the normal speaker output of PlayZX android app and there is a sort of zoom-out-vroom when entering a pause, the same noise that I heard through the speaker of the pico. Then I listened to the normal speaker output of ZX Tape Player android app and there seems to be a clear sound when entering a pause. I tried another test loading with ZX Tape Player and this time that zoom-out-vroom isn't there anymore. The difference now was that the phone sound level had to be 100% for games to load. In my opinion, this schematic works but if things can get better, then why not. :) I remember back in the days that I had to play with sound levels for some games to load and it looks like it's the same thing now.