When linking to these pages, please use the URL:
www.iki.fi/sol/ - it's permanent.
Back when we were moving to our first apartment that we weren't renting, we bought an amplifier in order to switch between audio sources in the living room. The one we got was Sony STR-LV500. It did a decent job, even though we weren't exactly using it for its intended purpose. I can't even remember which speakers we were originally using it with, but those were probably just stereo.
When we moved to our current home I hooked my old Logitech Z-540 4.1 speaker system to it so we could have a better movie experience. So yes, we were using a PC speaker set hooked to an amplifier. Not exactly ideal and definitely not what the pieces were designed for, but serviceable. The amplifier did not even "know" that the speakers included a subwoofer.
Fast forward to this year, and our poor STR-LV500 died, probably of heat death, because it was inside a cabinet and someone had stored some magazines on top of it. Oops.
Being able to watch movies (and stuff) in the living room being somewhat critical for a family with small children in this day and age, a replacement was needed. After looking at various reviews and prices for a while we decided to go for Sony STR-DN1080. Brought it in, hooked it into everything and it was fine.
One of the new capabilities of a modern amplifier, which seems to be a more or less standard feature these days, is that it can calibrate itself. You hook a calibration mic into it and run the calibration, and if everything goes well, it can then optimize the outputs so the sound in your room is great.
Turns out, the right surround speaker sounded really tinny and quiet, something we had not even noticed before. No worries, the amplifier can compensate and blast that speaker at higher volume than others. The overall sound sounded much crappier than before calibration though, and then I realized that the calibration option I had picked equalizes all speakers - meaning that it made all speakers sound like the worst one. Oops. Switching to prefer the front speakers fixed that.
The sound still wasn't exactly stellar, and there seemed to be a really small sweet spot in the room where the sound was nice, so we figured we'd get a proper speakers.
Looking at the price of proper speakers, we opted to go for an affordable 5.1 speaker set instead. The ones I looked at first were sold out in Finland. Then I found that practically all speaker sets were sold out in Finland, unless you were willing to pay thousands. So if I had to order from abroad, I might as well do more research on which set to buy.
Back to reviews and downloading various speaker set manuals, I decided to go with Denon SYS-2020. There were 3 or 4 sets I considered, all of them at approximately the same price range, all of them more or less identical in their advertised specs and all came with speaker cables even. One of them had a manual that kept warning about the order of powering things up or things might catch fire, so while I expect that to be overly cautious, I decided to skip it.
As a result now the amplifier can use the speakers as intended, can drive the subwoofer directly - earlier it just "thought" it had four unpowered speakers - and so on. And if we want to upgrade the speakers, we have something to upgrade FROM. The logical thing would be to swap the front speakers with something more expensive, but it's unlikely we'll ever do that. But the option is there.
After re-wiring the whole living room, including well over 30 meters of speaker cables, the resulting sound is clearly better. Sound literally fills the room now, instead of having just a small sweet spot. Wife kept playing her Queen records for a whole day at a pretty high volume.
A few more words about the new Sony amp.
First, it's a damn computer. The previous one probably was, too, but this is even more clearly so. It can play Spotify on its own, for instance. It downloads updates using wifi. It also comes with a remote control that is surprisingly nice to use - typing wifi passwords and such with a virtual keyboard using the 4-way control in the remote wasn't infuriating, which is a first.
It still lives inside the cabinet, but this time I added some PC fans to keep it cooler.
In addition to handling audio input source switching, it also has HDMI inputs and outputs, which is pretty convenient. I even ordered a "mini" AV2HDMI adapter to get the Nintendo Wii output to HDMI, but unfortunately the image quality of that converter was so bad it was unusable, so I still need to switch inputs in the video projector to play with Wii. Not that I often do..
The connections in the amp are pretty funny, because you have a bunch of HDMI inputs and outputs next to bare-wire speaker connectors. I wonder why speakers never standardized to RCA cables.
Like the rug in Big Lebowski, the amp really ties the room together.
This is not something I wanted to write, not this soon.
After we had had our first dog, Jana, for a few years, we figured that we'd like to have two dogs as they'd keep each other company. We went with mixed breed again, as they tend to be healthier. We felt that Jana was a bit too small of a dog at 4kg, we felt that a dog at around 10kg might be better. More robust, so to say.
We found an ad selling Sheltie mix pups, which concentrated more about finding good homes than asking for a lot of money. Sheltie is basically a miniature Lassie, and even at their heaviest they tend to be around 12kg, so it was a safe bet.
Kiku was born on a farm in the middle of nowhere, in a town where everybody seemed to have the same surname, and there was just one taxi in service. Luckily said taxi was around when we hopped off the bus, because otherwise we'd have been tad bit lost.
The taxi driver took us there and came in with us to look at the pups. The litter was mostly females, with a single male pup who looked extremely tired. That wasn't Kiku though. Kiku was the pup who managed to always escape the box in which the pups lived.
Apparently nobody knew what breed the father was, as nobody knows for sure who he was. The suspected dog - a stray - was slightly bigger than Kiku's mother, but not by a lot. Kiku's mom was running free in the farm and at some point became hungrier than usual...
We went back home and fetched her when the time was due. We set up a box for her to sleep in, but she didn't care for it, wanting to explore the world. We got her a doggy bed soon after.
She was basically housebroken from day one, scratching the front door when she had to go, sometimes in the middle of the night. I remember standing outside at 3am hoping the dog would just do its business so I could get back to bed.
She ended up being a bit bigger than expected. Her weight was around 20kg - not especially huge for a dog, but definitely not what we were expecting. That didn't really change anything for us, it was just a bit of a surprise.
Partially because of her size, she never begged for food. She didn't have to - she could just lean on a table and take food instead. We tried to train her out of this forever using lots of different tricks, but when she gets an instant gratification from doing the bad thing, what can you do?
And like all dogs she was repentant when she got caught, but that didn't really stress her. She didn't mind being yelled at, for, say, eating a whole duck breast off the table. But if humans yelled at each other... that stressed her to no end.
So we soon learned not to leave food on the table, as it might magically disappear.
There had been cats at the farm where she was born, and she had nothing against cats, to begin with. Then one summer she suddenly got deadly scared of cats. We suspect that while we were at the summer cottage, she had become curious about the cat some of our relatives had, and said cat hit her with a claw. After that every time she saw a cat she went into total panic mode, hairs sticking out of her neck and all.
On walks she was totally different from Jana. Whereas Jana just wanted to sniff around, Kiku wanted long and fast walks. Sometimes we would take the dogs on separate walks due to this.
Oh, did she ever love to run. While she was a young dog we lived in a neighbourhood with a couple of dog parks in a walking distance. She would get other dogs to run with her, and with the exception of a greyhound, she was always faster than any other dogs in the park. When she got to run freely in a forest, she was a furry rocket that you'd hear approach and then zoom away again.
She would run inside our apartment, jumping on a sofa so hard it toppled over. Our carpets didn't stay in one place for long.
On the sea shore, she was suspicious about water, but eventually learned to enjoy swimming in the summer, fetching floating toys that we'd throw in the water.
On one hand her fur was convenient so even in a muddy weather you could just wipe the mud away, she also shed fur a lot. We tried various brushes to help with this, but nothing worked until we found Furminator which worked like magic. That's not a sponsored link. The local birds have made their nests for years from the fur Kiku shed.
Apart from the eating-off-table thing Kiku was very obedient and kind dog, patient with children. One of the commands she followed was me snapping fingers twice - she would come right away. I never actively taught her that; it was just something I did naturally when calling for her, and it stuck.
She was our living doorbell. Hardly ever anyone needed to actually ring our doorbell, as Kiku would be barking at the door well in advance.
If we'd lay down in bed, she'd love to curl into a ball behind our legs. She stopped doing that a couple years ago, and seemed to prefer sleeping on her pillow in a corner.
Of all our dogs, she was the most stereotypically dog-like. Guarding the home, suspicious of strangers that would come to our home, tracking animals like rabbits or even people, etc. She didn't like it when someone left home without her, and was filled with joy when a familiar face came home.
She was a tracker, she was a shepard, she was a hunter, she was a companion. She was a good dog.
Her size turned out to be a problem when travelling. Taxis that didn't have a trouble with lap dogs wouldn't take us. In one particular case we got off bus and went to take a taxi, and all five taxi drivers at the bus station started looking in different directions avoiding eye contact. After we confronted them they said that there's one taxi that takes dogs, and luckily she was on duty at that time, so we got where we needed to go.
While it was never a problem finding a dog sitter for Jana, nobody really wanted to take Kiku, again because of her size. And when we did find someone who could dogsit Kiku, they'd end up getting dogs of their own, and oddly enough in every single case said dog was aggressive towards other dogs. Bad luck, I guess.
She was crazy about pizza. If we left pizza leftovers in their cardboard box on the counter, she'd eat the box. We learned to put the pizza boxes well out of reach.
After Jana died, we got a new puppy, Neko (yes, we know what it means, that's the joke). Kiku really did not like the newcomer, and it took several weeks for them to get along. Eventually they did play together, both of them initiating play at one time or another.
We did know that Kiku was a rather old dog, and being a larger dog than Jana had been, she probably wouldn't last much longer. In fact, before Jana died we wondered which one would go first. Statistically, larger breeds tend to live shorter lives.
We noticed a month ago that Kiku had lost weight. The vet said it's probably just due to old age, but that the weight loss is not good. So we increased her diet, and she regained weight, albeit slowly.
Then one evening we noticed that one of her hind legs was noticeably wider than the other.
The vet took x-rays and said she had never seen anything like it. It was an aggressive tumour, and it was inoperable. Removing it would basically require completely removing the whole leg, and even if she survived that massive operation she was such an old dog that she probably wouldn't learn to live on three legs. And it was likely that wasn't the only tumour.
Additionally, the vet told us on the phone that the as the tumour grew it was bound to cause her constant pain, which dogs are notoriously good at hiding.
Jana's passing was sudden and tragic. Jana had had a lot of health problems before that, though. Kiku had been a healthy dog most of her life, rarely needing any medical attention, and even then it was about small things like cleaning of her teeth or some antibiotics for infections.
We wanted to do right by her. Should we wait? Wait to see her condition rapidly grow worse until she can't even stand up by herself, or when she has trouble pooping? Or should we let her go now, before her condition got unberable?
We reserved a time for her to be put down about a week later. Today.
We bought pain medication for her and continued with life. During that week we noticed that she was getting up more rigidly. We noticed that she didn't want to go down stairs - a pitiful obstacle that had probably never even crossed her mind before. And this with the heavy pain medication she was under. Like the vet had said, it was clearly time.
She loved to tear used napkins to pieces.
If you knew you'd be dying next Tuesday, would you want the days to be special, or ordinary? We opted for as ordinary as we can make it, except she got more treats. No need for her to steal food off the table, we simply gave her all the leftovers.
She loved to eat fish.
During that week, it was strange to find ourselves already missing someone who was still there.
Why does it hurt so much?
Last night we ordered pizza, because she had loved it.
She was stressed about our crying for her.
Now she's no longer in pain.
And I know my pain will fade.
Update 5th April: The patch was not accepted upstream, which I understand and respect, so I've posted fork on github if someone wants this.
Once upon a time, I made a virtual filesystem called CFL (for "compressed file library"). The idea behind the library was to have a bunch of files in a single file, each filtered and compressed separately for efficiency, and then have applications access said file as if the contained files were separate files.
Additionally, several of those files could be mounted at the same time, and if duplicate filenames existed, the mounting order would dictate which file was opened. So, if you have your main game data as one file, and another one for "patch" data to override the main game data, you have a game mod system.
This isn't exactly a new idea. For example, DOOM .WAD files work this way. Nor was I the last one to do something like this. Possibly the most popular incarnation is the oddly named PhysFS library.
The last release of CFL is called CFL 3r3, being the third release of the third rewrite of CFL. That release is from 2009. I had a lot of crazy ideas for the next rewrite, including even more complicated filter system which would basically have required a scripting language to perform the compression. One of the ideas I had for that rewrite are magic streams.
Now that it's 10 years since the last CFL release, and I'm not seeing much of a chance that I'll spend time on doing another rewrite (even though I've started several times in the past 10 years), I got the idea of implementing the magic streams on PhysFS instead. I've sent a patch to Icculus, and we'll see if he feels isn't a good idea to include it or not.
So, what are magic streams?
Back when the original Xbox was a thing (to be confused with Xbox one), all games were released on physical, spinning discs. Seek times on such a media is huge. One of the release requirements from Microsoft was that games should start under certain time limit, and I remember reading from post-mortems how some teams had trouble hitting those time limits.
Magic streams help with this by completely eliminating seeks from file i/o.
Using magic streams is a three-step process. First, implement your application. Second, record magic streams. Third, use magic streams.
When implementing your application, you will open and close various files, seek around, read bits here and there. Maybe one file tells your application to load other files. Level files may read mesh files which may read texture files, for example.
Recording magic streams is done by first identifying deterministic file i/o segments, such as initial game load or level loads, and adding code that writes all file i/o into a linear file.
Using magic streams simply replaces those recording commands with reading ones. Your application still thinks it's opening various files, seeking around, etc, but in actuality everything is read from a single, linear file. File opens and closes become no-ops. File seeks become no-ops. Ftells actually read values from the magic stream.
The magic stream itself can also be compressed to reduce disk i/o further.
The obvious downside is the potential additional disk space usage. If a file is used several times by an application, it will probably be included in one or more magic streams as well as potentially being included as is. Also, patching applications becomes more of a hurdle if a resource that's included in a magic stream is changed.
Automating magic stream creation may also be tricky.
Modern technologies like flash media, SSDs and huge disk caches reduce the benefits of the magic stream, but does not eliminate them completely. I do not (as of yet) have any real data from existing games, as setting such up takes time, but my synthetic benchmark shows a case where using magic streams speeds up file operations so much that the test only uses 25% of the base time. This is, however, a synthetic benchmark and actual results will depend on the use case.
Synthetic benchmark results Without magic streams: ======================================== 416ms With magic streams: ========== 98ms
One of the doomsday scenarios going around is the false vacuum, a theory where our universe exists as a bubble that may collapse at any point.
On a walk today I started pondering about what it would look like if this was the case, and considered sending a mail to xkcd "what if", but it would probably be ignored. So I kept pondering.
Let's say the collapse happens at the speed of light or faster (because, when talking about universe-scale things, laws such as speed of light don't necessarily apply) we don't really need to care about it, because we won't have any warning. It just happens, and from one moment when everything exists, everything stops to exist on the next.
If the collapse happens slower than the speed of light, things get more interesting. The farthest star we've detected so far (as of April 2018, anyway) is about 9 billion light-years away. The light we detect that originated from it has spent 9 000 000 000 years travelling. Let's say the collapse happens at 99.999% light speed. When it hits the star, light has just escaped it and races towards us, and when it finally reaches us, the collapse has spent those 9 billion years racing behind it, only 0.001% slower, and when we have a chance to notice that something is wrong, we'd have.. 90 000 years left. I'm pretty sure that's enough time to crypto currency mine ourselves to extinction.
But what would it look like? Would space just cease to exist, or would it contract? If it contracted uniformally, we wouldn't see anything weird happening, because we also exist in the same space. Well, laws of physics might break, but if that was the case, we wouldn't be around to notice it. Not for long, anyway.
How I'd imagine it would be that space contracts very steeply at the border, so it would look pretty much like a wall of black hole approaching us. How large the event horizon would be I am not qualified to figure out, but that border area just outside the event horizon would be rather strange. Stars would seem to accelerate steeply away from us and then disappear.
And it would be a wall, not a sphere, because the probability that we're at the center of the universe is rather small. We're likely to be somewhat off to some side, and thus the collapse would look like an approaching wall to us.
None of the above has any real physics behind it, because I don't have any theoretical physicists on call, but it's interesting to think about, nevertheless.
Now, what if the area outside the event horizon was really, really large? That would mean that it would seem like the universe was expanding, everything accelerating away from us.
Which it kinda does look like..
I consider myself a nice person. When someone asks for help, I tend to do so, unless they're approaching the matter as if they're owned something. A little bit of humility goes a long way.
Sometimes things that are difficult for someone are easy for me, and I go out of my way to help.
And then, there are situations where we do something wrong. We own our mistakes. We apologise. We try to make things better.
If, for example, our dog does something, we do something that nobody in this town seems to even consider: we apologise. We try to make things better. When I've been in situations where a dog escapes a yard and comes barking at me, scaring me, it seems like nobody apologises. (This has happend to me several times, different people, different dogs). In some cases they're just angry at me, as if I did something wrong that caused their dog to escape their yard and come barking at me.
At one point I held a door open for someone so they don't need to - and thus we both would continue our journey faster - and the person stopped and started calling me names for some reason.
I live in a town with both finnish and swedish speaking people. It feels like many of the swedish speaking people absolutely refuse to try to comprehend what I'm saying. When they talk, I try, with my limited swedish, but talking to them feels like they consider me a sub-human. If I say happy new year to people, the finnish speakers answer, the swedish speakers act as if I didn't exist. Mind me, not everybody, but this has occurred several times in the past few years.
It feels unfair. Why must I be nice when nobody else seems to bother?
It's because if everybody was nice, this would be a lot nicer place to live. I want to make the world a nicer place to live in.
It becomes even harder when people are not nice to you in a way that you can't publicly talk about it, because then you become the target, you're the bad guy, even though it's you who have been wronged.
There's freedom of speech, but not freedom of consequences. Even if you're in the right. People who are not nice to you might be able to be really not nice to you if you rock the boat.
And so it feels unfair.
I hurt. I feel bad. And I can't even talk about it. It's not physical. It's not material.
I'll be fine.
About six months ago I was visiting some store with my family and there was a test unit of the Alesis DM Lite kit on the store floor. My son tried it out and said he'd want one to play with. I checked the prices once we got home and it's pretty cheap - around 200-300 eur. I can't remember the exact price (and we bought a bundle anyway) and I can't seem to find it for sale anywhere anymore. Since the kit also works as a USB MIDI device I figure it's not a total loss if the kids get tired of it.
The kids got tired of it.
I plugged the kit to my PC and tried recording something to Reaper, and.. it didn't work out. For some reason the data wasn't in the format the program expected. I left that be for a few months, and came back to it just recently.
I figured I could use a MIDI feedback driver / virtual MIDI cable (the one I actually used was loopMIDI) and a simple program that listens to the drum kit and transforms the commands to whatever the DAW and/or VSTs expect. This was actually pretty easy to do using the RtMidi library (which I find much nicer to use than PortMidi - I'll have to change SoLoud piano demo to use RtMidi at some point).
After setting things up to transform the commands to whatever NI Polyplex wanted, things were much more fun. The drum kit itself contains a few different sample sets but nothing really "fun"; by using VSTs, you can have just about any kind of sound, and feed it through filter stacks too for even more crazy experience.
That's when the trouble started.
The connection to the drums seemed to die in 1-20 minutes, totally randomly. In the interest of brevity, here's a list of things I tried (but are not limited to):
Sending timing messages back to the drum kit.
Sending dummy note on messages back to the drum kit.
Sending actual note on messages back to the drum kit.
Disabling Win10 USB sleep power option in power plan.
Disabling Win10 USB sleep in device manager.
Restarting the USB port with windows driver kit devcon.exe.
Updating to Windows 10 version 1809.
Changing the drums to a powered USB2 hub from motherboard USB3.
The last bit seems to have solved the issue. Now, what I think happens, or has happened, is that in pre-win10 versions windows had this funny habbit of "checking" if USB devices are awake by shouting at them all the time, causing them to stay awake. This was pretty bad for power saving, but made it possible to make USB devices that left keeping the connection alive to windows.
Then Microsoft fixed that behavior, exposing the bugs. I've seen some USB devices which outright refuse to work unless you explicitly set the USB power saving off in device manager. For some reason turning those options off did not help in this case, which may be a bug in windows. There's also probably a bug in the drum kit itself that leads to the connection not being kept alive. If either of these bugs didn't exist, this wouldn't be a problem.
When I moved the cable to the powered hub, I took away windows' power of powering off the USB port. Moving from a USB3 to a USB2 port may also be a factor. In any case, there's a workaround, and there's bugs somewhere, possibly in multiple places.
The utility can be downloaded for windows here on github.
To rephrase myself from last year, let's hope 2019 ends up better than 2018 was.
2018 wasn't exactly a great year for me personally, and the global politics didn't look too great either. Maybe this year will be better?
Take a deep breath, and have a zen moment with the new year's demo:
Last year my mother died, followed (within days) by my dog dying. On positive side I finally got over my SoLoud burnout and got a new release out, which fixes tons of bugs. I also got the SoLoud manual out to print, so if you want a physical copy of the book, just use your favorite online bookstore, it might be listed there.
I did not manage to write more, even though I hoped to.
I did, however, get a VR kit together and tinkered a bit with it (see the demo above for an example). I did not finish the zx spectrum game I've been tinkering on, but I managed to make a build system by accident.
I won the 20th TMDC. There has not been a TMDC after that.
So what will I try to do this year?
I want to release a game. As in, for money. Itch.io is a likely platform. Steam, I suppose, could also work since they publish basically everything now. I already have a bunch of game prototypes I could start from, I just have to pick something I can realistically finish in a very short timeframe. Don't hold your breath though, as game projects tend to eat deadlines for breakfast.
Since it's trendy, I'll try to form a new habit or two. I've been solving some puzzles in the mornings for a month or so, so I figured I could throw money at brilliant.org and work through their material in the mornings. Everything there seems to be bite-sized so it shouldn't be impossible to do just a little bit of that every morning.
My doctor has also told me to track my blood pressure. That's another thing that needs to be a habit that I do regularly or I won't remember to do it.
Those three things should be more than enough goals for one year.