PiAno Project, Vol 1

December 30th, 2016 (permalink)

I've been working on another simple speccy game and should be able to get that more or less done soonish. On that front, dropbox is going to remove the public folders pretty soon, so all of my online speccy emu links are going to die. I guess I should investigate hosting my own speccy emu so that all the pieces are on the same server...

On other news, I figured I could try to make a simple hardware project. Writing about these projects is usually a death warrant for the projects, but I'll hazard it anyway. Basically, I bought a cheap toy piano:

It's really cheap. And really crappy. The idea here is to put one of these inside instead:

There's a bunch of challenges with the project; it's entirely possible this will fail.

The Raspberry Pi Zero has enough GPIO to handle the key input, but it has no audio output nor does it have network interfaces of any kind.

I considered various options on developing software for the Pi. I tried getting a virtual Pi running under windows, but the available images that I could find are all too old to support the Pi Zero, so I couldn't get the simulation running. And in any case, development cycle would have been rather long - develop, compile, save disk image, write whole SD card (taking tens of minutes), boot up on the device..

Second idea was to install some Linux-file system drivers on windows so I wouldn't need to do the whole-disk-image write thing. But that would only have let me copy files over.

So in the end the only sensible thing to do is to get network connection to the device and compile on it. I could still do all the editing on desktop. If I wanted, I could even set up samba on the device, and let it see the same files immediately, but copying over with scp should be enough.

And since it's a 1GHz ARM device, compilation times shouldn't be impossibly long.

To get the device running at all, I hooked it to a USB keyboard and HDMI cable to my monitor. The keyboard didn't work - possibly because the Microsoft Natural Keyboard Pro is also a USB hub and all sorts of things. When I switched to a simpler USB keyboard things started running.

Next I added a (passive) USB hub between the keyboard and the Pi, which worked. Then I added a wifi USB device, which still worked, but after struggling for quite a while to get it running (following some surprisingly long lists of things one must do on Linux command line to get to wlan), I found out that the specific wifi device I was using required some kernel mode driver that wasn't included in the image I was using.

Good news was that I found the simple command I could use to download the driver. Bad news was that without network, I couldn't download the driver.

Off to a local computer shop I went and bought a USB Ethernet device instead, and that worked:

..well, not before figuring out how to get the SSH daemon running, but that turned out to be as easy as running "sudo raspi-config" and digging through the menus. After that, I could just disconnect my HDMI cable and keyboard, and continue through ssh. Which means that the only things I need plugged to the Pi right now are the power USB cable and the ethernet USB dongle.

There's a lot of warnings regarding plugging the raspi to "bad" power sources (like batteries), but apparently the PP1 is positive and PP6 is the negative pad to use for 5V power. Since I want this to be an untethered device, I'll probably want to solder wires to those pads and just hope battery power works. What's the worst that can happen, right?

The Pi Zero has no audio output, but one could be built. I considered this for a few seconds, and then ordered a $1 USB audio device off eBay. It'll arrive sometime in the future. Hopefully. There's still a lot to do in the meantime so I'm not all that worried about that.

So development cycle is pretty much solved, audio i/o will be handled by that USB thingy, power will probably work. What about the piano itself?

First off, even though the piano is much smaller than I expected (and the 37 keys of the piano are slightly too little for my comfort), there's plenty of room inside the case, so fitting the zero there won't be a problem.

In the image above you can also see the helpful colors of the wires. I guess they've just used whatever wires they got their hands on with no plan whatsoever.

The different components and bits are connected approximately like this:

Note that the red wires are actually ground, and the white wire (green in that graph) from battery is VCC. Yay. The ground wire to the OpAmp board is directly connected to one of the blue wires going to the Blob Board, so it's also ground. I guess one of the remaining blue wires to the Blob Board is VCC and the final one is the audio signal. There's also a microphone, which they probably felt was a good idea at the time.

From the looks of it, the OpAmp itself gets raw VCC, but the blob board's power is filtered through a capacitor. Also note the silk print of "FM" - I guess they have a version that has a radio built in too, which uses the same board.

I intend to keep the OpAmp board but ditch the Blob Board.

The blob contains the brains of the operation. Maybe the blob is there to protect their intellectual property, or maybe it's cheaper than actual casing for the chip. In this case I don't think there's much to protect... although, who knows, maybe the same blob drives the versions that have FM radio or the MP3 player, so maybe there's something highly sophisticated under there. I don't care, though, that simply has to go.

Looking at more functional bits, the piano keys are driven by two ribbon cables, which leads to a bit of a mystery..

There's 4 and 6 wires in the ribbons. A "normal" keyboard matrix would mean 4*6=24 individual buttons, but there's 37 here. So they're probably wiring three (or more) wires to each button, and to figure out which one to use they have to cycle through more combinations.

The ribbons go to the "other keys" board. There's 8 buttons..

..and just one unique wire for them. The additional buttons share one wire from the 4-wire strip and all of the 6-wire strip with the piano keys. So all of the 45 buttons are wired with just 11 wires to the blob. On the positive side, that means I'll only need 11 GPIO pins on the Pi Zero.

And that's where I'm at. I'll need to do a bunch of soldering, taking out the Blob Board, solder connector for the pi zero and so on. After I get the wires to the GPIO pins, I can do some software work to check what kind of scanning I need to do to find which buttons are pressed.

MuCho and Word Chains

November 4th, 2016 (permalink)

I figured I'd revisit the idea of multiple-choice adventure engines, and wrote one for the zx spectrum. The result is MuCho - release thread here - actually that's the third release, but anyway. You can also download the zip of the release, or if you prefer, take a peek at the example .tap files or the 56 page pdf manual. Or html one. Or epub or mobi. Take your pick.

The source code to the compiler and engine are on github as usual.

You can try playing the demos in an online zx spectrum emulator too. The links work right now on firefox, but there's no saying when something will break: blackjack complex dukes simple traveller waiting where "waiting" is the big game.

Along the way, to stress and develop the engine, I looked at a bunch of gamebooks (gamebook, choose your own adventure, cyoa, or multiple choice adventure - many names for the same thing) and found one on the net that just fit in the 48k speccy after multiple compression tricks. Then I spent several weeks hunting down the author for permission, which he, lucky for me, gave.

The compression is something I might write a few lines about. There's no disc on the speccy to load from, so unless you go through the effort of loading more stuff off tape (which would be rather complicated), everything has to fit inside that 48k of memory. 48k, which also includes the framebuffer. I managed to fit the engine, a 4k uncompress buffer and about 29k of compressed data in the device.

For compression I use ZX7, which is a very good LZ-based compressor (in the same family as lzw or lzss) with an extremely tiny decompression routine for the speccy. Being lookback based compression it doesn't do well on tiny amounts of data, so first thing to do logically (although I didn't do things in this order) is to compress multiple "pages" of the gamebook at once.

But which ones should we compress together? Hey, we have processing power, let's just try it out. And so I did; my compressor goes through all combinations and picks the combination that results in the highest compression ratio.

That still means that the first "page" doesn't compress well, because there's nothing to "look back" to. So let's put something there. Luckily the ZX7 compressor supports looking back behind the start of data, so if I put something useful in that memory, it can use it.

For this, I analyze the whole gamebook, looking for the most common words, and the words that follow those words. Then I generate up to 1KB of text by taking the most common word, and then chaining that with the most common word that follows that word, assuming it's in the list of most common words. This improved compression by about 20% in some cases. Yes, it also means I have to store that uncompressed data before the uncompress buffer, but those were included in the gains calculations; it's a net win.

Of course that only improves the first "page" in the compression buffer, so I could analyze what bits go to the start of the buffer and only use their data to generate the "training data", but.. eh.

There's probably some algorithm that would generate the optimal data to put in this lookback buffer, which doesn't care about such things as "words", but I doubt it would do dramatically better than what I already have.

The generated word chains look pretty funny.

    "I think I'm trying not getting out from his feet You open them 
    with long as he says. "We should just about make it.

    the other young men were a couple of them into this cat right 
    for me. I had been pretty to index    

These got me thinking that I could develop this idea further. It's not a new idea - they're basically Markov chains, nodes with multiple exit points at various probabilities. There's probably tons of chatbots that use the same idea.

I downloaded a bunch of texts off the net and built several corpuses to feed my "word-chain generator", and got to work. The first step was to do a pure chainer; I would pick word tokens from the source text and record their follow-up nodes. To know when to start or stop, I'd flag some nodes start nodes and others end nodes, depending on whether they're at the start or end of a sentence.

The result was moderately funny gibberish.

(I guess I could go back in versions in git, but I'll simulate the result using my latest version and forcing the word chains to 2)

    The wild tempt not be the power hath he sits and chasmal difference 
    between her She could solace in the direct line of thee love before the plot.

    Thou art an answer little time to such guise That looked like Eldorado.

    Ye who is curious.

    For thou me?

    Tell me in wearing away his youth in her globe was there How fares good 
    critique on the man trembled as before Thy gentlest of Time.

    I will be admitted at the haunt of the word Nevermore.

    I am by opposition.

    Inurned and radiant hours Saw only a becoming carriage much of The rhythmical theirs?

The corpus I'm using for this is the works of Edgar Allan Poe from Project Gutenberg.

While that's funny, it's not horribly coherent, so I basically rebuilt the whole system to consider longer word chains. I would build sparse tables containing hit counts for up to 7 word chains, and whenever storing those word chains I would also store 6, 5, 4, 3, and 2 word chains.

When generating text, I would consider all available chain lengths, weighted so that the code prefers longer chains. The results are much more coherent. Here's some strings from a 40's sci-fi corpus:

    You're getting nowhere.

    A commercially feasible plan for making an aluminum alloy stronger 
    than the best steel so that it and couldn't.

    That was just taking advantage of it.

    Maybe we were meeting for twelve hours on earth would want to put him 
    again in a perfunctory way.

    The ports and then you that stared at the Cultist.

    I have led a sphere to give us by now.    

Quite bit of work went into picking sane data from the source data. In the end I changed my logic to just discard the whole sentence if the parser isn't sure what's going on; that removed a lot of garbage from the output (but also discards a lot of possible word chains; using large corpuses helps).

I also built a corpus of legalese, concatenating various software licenses together;

    Current Maintainer to be licensed at no charge to all third parties under the Initial 
    Developer in the Source Code notice required by Exhibit A.

    You may add your name as a Contributor to the Program is provided solely for installation 
    by end users according to a third party.

    Licensor or such Contributor as a result of any such terms You offer.

    Its Investigation Of The Program Is With You.
    Such Limitation.    

    To The Quality And Performance Of The Program Is With You.

Sometimes the results are funny, other times they're boring. Feeding the system some speeches by Trump for example ended up with some funny bits. The bible works pretty well too. I won't quote those here for obvious reasons. Here's some generated Shakespeare (Gutenberg project, again):

    We will talk of brotherhood? 
    But in balance here together. 
    I laugh this palpable device? 
    I grant We shall you say? 
    As water is dress'd in. 
    What doth yours: 
    As kill my hand; 
    I quickly shed Some of grief!     

The sources to the word chain thingy are on github and win32 binaries are can be grabbed here. Comments welcome as usual.

Piston Cup by Ravensburger

September 25th, 2016 (permalink)

Let's look at yet another kid's game. I picked this up from Lidl at some point, and we've played it on and off. Basically it's a travel-form factor board game; you play as the cars from, well, Cars, racing on a track. The track consists of 14 pieces you can put in different orders to form slightly different tracks.

The pieces are:

  • "start" piece
  • "oil slick" piece which makes you go back one step
  • "crash" piece which causes you to miss your next turn
  • "boost" piece that gives you a new turn
  • "tight" piece where only one car can go at the same time
  • a bunch of "normal" pieces where two cars can go at the same time.

The rules are simple: roll a die (6-sided die with 1,2,2,3,3,4 sides - so 1-4, where 2 and 3 are more likely than 1 or 4), move forward how many bits it shows. If the road is blocked, you must stop. If you land on a special piece, follow the instructions. If you hit the start piece, you must stop. Whoever finishes three laps first wins.

When building the track, two special pieces must have at least one normal piece between them.

So, we have another game with zero player agency, so let's monte carlo it. I wrote a simulation of the game, using one of the example tracks from the manual, and ran a million races, and the results are:

2 players 3 players 4 players
1 566263 415743 354693
2 433737 359426 324739
3 - 224831 208280
4 - - 112288

There's a HUGE advantage at going first. In a 4-player game your chances of winning if you go last are mere 11.2% (as opposed to the expected 25%) whereas whoever goes first wins over 35% of the time.

Increasing lap count evens things out a bit, but not by much; in a 4-player 20 lap game, the player who starts last has 19.8% chance of winning while whoever goes first wins 28.3% of the time.


June 22nd, 2016 (permalink)

Once upon a time I got inspired to add RSS feed to this site. I updated the RSS script manually. Then I got bored of updating it, found an online service and just wrote my last RSS update that linked to said service.

The service shut down recently. I could have picked one of the dozen or so alternatives, but figured I might as well get it out of the way and wrote a simple tool to generate the RSS feed from the .html file instead.

So long story short, the rss feed is live again, as long as I remember to run a script file every time I update this blog. I do wonder, however, how many people actually use the feed. When google reader shut down, I tried a couple rss reader alternatives but in the end just stopped reading rss feeds.

The most annoying bit about the rss "spec" (apart from the fact that there are at least three specs) is the date field. If you look at the feed you'll note that I always seem to post at the exact same time of day.. that's because I only have the date stored. Converting from "April 7th, 2016" to "07 Apr 2016 12:34 UT" felt like unnecessary work, but hey, the w3c feed validator now says the feed is ok.

The scrubber tool is so specific to this site that I don't plan on releasing it or its sources. I probably should have written it in python, but I used c++ instead just because it's been so long since I touched python again.

Aaand that's about all I have to say about that.

Advent Rising and the Waste of Potential

April 13th, 2016 (permalink)

I finished my Steam backlog some time ago. Like many people, I had managed to generate quite large backlog of games I didn't play when I acquired them, thanks to various bundles out there. Most of these I tried for a few minutes before uninstalling, or simply archived based on the game's genre. Point is, I ran out of stuff to churn through.

Then I looked at my GoG backlog. Yeah, I have a bunch of games there, too, that I had ended up with and hadn't tried. I browsed the games and picked Advent Rising, because it looked interesting and had some positive reviews.

The game boasts having Orson Scott Card of Ender's Game fame as a screenwriter, so I had rather high hopes on the story.

As a warning, this blog post includes blatant spoilers for the game. Not that I recommend you play it, though.

The game is rather old, and definitely hasn't aged well. There are a lot of older games that look much better. The controls are flaky, the world doesn't feel "solid". The level design shows that they had issues with the controls, because apart from a couple instances of "platforming" (and even those consist of two jumps a piece), the geometry is fairly easy to navigate. There are some places where you must jump to get to a ledge, and for some reason the character's basic jump is just tiny bit too powerless for these and instead you need to use a charged super jump. The basic jump seems to be there primarily so that you have an easy way to get out from the frequent small geometry glitches.

The game is very unstable. I would chalk this up to trying to play a 2005 game in 2016, except that based on the game's FAQ the same crashes on scene transitions were in the game at release. There's other, more funny bugs too - early on in the game I was supposed to ride on a car driven by the game's AI. The AI decided to run to a wall and couldn't get out of an infinite loop of reversing a bit and then running to the wall again. So I had to exit the car and traverse the landscape on foot instead, dodging the enemies designed to attack the vehicle.

Talking of enemies, the game pretty much consists of running from point A to point B, fighting or ignoring the same bunch of enemies over and over again. There are some boss fights, couple of which can only be won by repeating a specific trick which may not be obvious (so a walkthrough is handy).

Sometimes it's also unclear what you're supposed to be doing. As an example, there's a certain type of enemy ship that you fight and/or pass by in the world, and then at some point you're all of a sudden supposed to ride one.

Towards the end of the game there seems to be some story discontinuities, with some things happening without warning or explanation. I presume they ran out of money or time and just assumed nobody would notice. According to wikipedia, the publisher had a million dollar competition for players after the release - spending that money on further development might have made more sense.

At one point when running after a bad guy a random bounty hunter appears and you end up in a boss fight. This is not foreshadowed by any way nor it is explained, or referred to, later on in the game.

One cutscene shows your character barely on his feet stumbling across a tunnel and saying he has a headache. This, too, is completely detached of the whole.

An alien brain control robot of some kind appears on one cutscene without warning and controls a big alient you end up fighting. That's the only instance of such a thing, and you have no idea what it was when you saw it the first time. Why you didn't just fight the big alien without such a brain control robot, no idea. The game throws aliens at you to kick butt without any explanation anyway, so you didn't have any expectation for an alien to be friendly.

You're captured in one cutscene and then just run around without your captors when the game returns control to you with no explanation on what happened.

And so on.

So what about the story? The story starts out strong, and then pretty much flops. Basically there's a first contact situation with an alien race, and when humans go to talk to them, they just say that they're sorry, but all humans are about to die because another alien race is coming to wipe them out.

That's the best bit of the game.

After that it's just repetitive running around kicking alien butt. The story runs you through a bunch of samey environments interspersed with cutscenes where more or less everybody you've ever met dies. The game includes one choise near the beginning which basically says which order people will die, and the most major change in story is at the end battle, which happens after the credits have rolled. So yes, to see the effect of your choise, you need to play the whole game from beginning to end again.

Oh, and humans are pretty much demigods, their potential just needs to be unlocked somehow. After you learn a couple of psychic thingies you can pretty much just ignore the weapons dropped by all the aliens, and keep spamming force waves or whatever. The various alien species have a religion that orbits around humans, which most of them don't believe exists. There's strong hints that there's more to this in the story, to be revealed in sequels.

Yes, sequels. The game was supposed to be the first part of an ambitious trilogy, with companion novels written by Orson Scott Card. Neither of these things materialized as the game flopped. I suppose the follow up games (and books) would have revealed more about the universe and about how humans got those powers (and how the heck nobody in said universe hadn't stumbled upon said powers by accident).

Now, during my steam backlog rummaging I've gone through tons of really crappy games, but for some reason they didn't cause me to write a 800 word negative review. The reason why this game in particular irks me is the huge waste of potential. The game is about 90% there - it feels like the the second 90% is missing.

A pity.

Xenyx Noise Fix v1

March 15th, 2016 (permalink)

So the problem appears to be the USB ground, causing the Xenyx to boost the noise in the ground signal into the output audio signal. I figured that a reasonable workaround for the time being is to stop using the Xenyx as a USB audio device, and power the Xenyx off a separate USB power plug, instead of using the PC, and to use a separate (sub-10$) USB audio device as the second device.

This is by no means an optimal solution, but it does come with the additional bonus that now I can wire the PC's audio output to line input instead of 2-track, and thus use the low/high pass filters and panning control on PC audio, meaning that if I'm watching a particularly noisy lecture on youtube, I can actually do something about it.

Based on the research I did while hunting for a fix, a "proper" fix would be a USB separator. Or buying a more expensive mixer, maybe. Or a more expensive sound card, perhaps.

I'm titling this post as "fix v1" in hopes that there's a more proper fix downstream, but I'm not holding my breath. At least the noise is gone!

Xenyx Noise

March 15th, 2016 (permalink)

Some time ago on this blog I posted about a cheap hardware hack I used to enable several audio inputs. That was, in the long run, a rather bad solution, so I went and bought a cheap hardware mixer with USB input, namely a Behringer Xenyx 302usb. I like it, it does everything I need (more or less), but it picks up noise from my PC, and that's rather irritating.

I need two audio devices so that I can dedicate one to Windows system sounds (and other audio applications) and have one dedicated for synth output for lower latency.

I've managed with the noise by setting the PC to output audio at maximum volume and having the mixer's volume low, but there's limits to how much this helps, and I'd like to have some breathing room with the volume adjustments. Also, some games output audio at relatively low volume, so I have to increase the volume, and thus, noise, in those cases. Anyway, it gets irritating after a while.

The noise source is clearly the PC, since if I move windows around, the noise changes. However, if I plug headphones (or speakers) directly to the PC's audio output, the noise is not noticeable (i.e, the audio signal is WAY higher than the noise floor is - I'm pretty sure the noise is there if I'd up the volume enough).

There is no noise if I only play sound through the Xenyx' built in usb audio interface.

The noise is there if the input is plugged to the Xenyx' line input or 2-track input. The noise is there if I use the PC front or back audio plug. The noise is there if I plug a separate USB audio device to the PC and use that as the input, even if that device is plugged to a separate, powered USB hub.

Since the noise is also there when the audio plug is not connected, but touches the computer chassis, I suspect that the noise is coming from the ground of the PC (and that carries over through the USB hub), and the Xenyx somehow manages to amplify it. The fact that the noise is NOT there in the Xenyx USB input is a clear plus for the Xenyx.

The "obvious" solution would be to ditch the Behringer device, but I'd love it if there was some easier (and cheaper ^_^) solution.

As a voodoo thing I also tried some ferrite rings, but those didn't have any effect.

UPDATE 1: Tried taking power to the xenyx from a usb charger plug instead of the PC's usb, and noise goes away. But that way I can't use the USB device in the xenyx, so that's not a solution.

UPDATE 2: Yes, I could use another external USB audio device as audio input, and only use the USB on the Xenyx as power source. That did remove the noise and let me use a separate audio device for synths. Not ideal - ideally I'd just use the xenyx as the audio device - but works. I just need to buy a usb charger thingy to power the Xenyx, I guess..

Hunting Microspikes

January 30th, 2016 (permalink)

We've used Kahtoola Microspikes for some years now, and even bought some for some of our relatives. They are simply easiest way to survive in the slippery seasons in Finland, although you have to take them off whenever you go indoors (for example shopping). I've mentioned these on this blog before.

Now then, another relative of ours got interested in said spikes, so we promised to send a link to a local webstore that would sell them.. and couldn't find any. We did, however, find something oddly similar - "Snowline Chainsen Pro". I googled a bit and judged that these are probably some cheap knock-offs, but decided to dig a bit deeper.

The Kahtoola site lists patents. One of the patents describes the microspikes pretty clearly. The inventor is one "Jin-Hong Choi".

Snowline's CEO is one "MR. JIN-HONG CHOI". Interesting.

Googling even further I could find at least three separate websites for Snowline, with this one listing company history mentioning that in 2007 they "achieved export to American brand 'Kahtoola'." Other brands include "Mont-Bell", "Zamberlan", "Snake", "Koch Alpin", "Mt. DAX" and "Crazy Idea". Why their own brand is only now making headway internationally I have no idea.

So apparently Snowline is not a "cheap knockoff" like I first thought.

Return of the Recent Search Terms

January 22nd, 2016 (permalink)

A while ago someone mentioned that I haven't done a recent search terms post in a while. This is true. I figured I'd do one now, and looked back to see what dates I should include in the search, and was surprised to find that I didn't do a RST post last year at all!

Google has become depressingly good at filtering funny search results from the reports, however. Google analytics only gave about 600 keywords for the whole year(!), and from them, I only found the following mildly amusing ones.

You can find collection of older RSTs at this rather long page

avr circuit simulator for ubuntu atanua

Sorry, never got around to implementing it, even thought I got sources to an avr simulator and license to use it.

common stories of sol

I guess I do repeat myself sometimes.

concept of lookup table in graphics tutorial

Concept. Okay. First, calculate something. Then, realize you're calculating that exact same thing a lot. So how about storing the value and reusing the result. But you have a range of values. So instead of storing one value, you store a table of values. And that table is a lookup table. Not really limited to graphics, though. Common lookup tables in graphics (historically) are color lookup tables, screen offset tables, and trigonometric tables, such as sin and cos, for old enough machines where calculating those is really expensive.

death rally creators dos

That would be remedy entertainment.

how to make a audio engine in c++

Through a long, tedious, but also rather interesting learning process.

how to port dos program to windows

Learn DOS programming. Learn Windows programming. Not necessarily in that order. Now you know how.

how to use escapi

Look at the example source code, maybe?

want to make a mmo how to get started 2015

Same way as before: learn absolutely everything about everything first. And/or become rich.

webcam dll multi device support

Depends on the make and model of webcams. Some work, others don't. Most people don't use multiple webcams at once, and thus the developers don't always expect that.

white magic spells that work

Click here to feel better.

why are busses so loud

They are relatively heavy vehicles, and thus require rather a lot of energy to move, and acoustics isn't the primary concern. While I do believe that it would be possible to design a bus that's fairly silent, I trust that people would prefer just getting whereever they're going at a cheaper rate than ride on a bus that doesn't make so much noise.

Happy 2016

January 6th, 2016 (permalink)

And the Pouet thread, too.

Haven't written a breakdown as of yet. Any interest?