The ogo-shell utility is a file-browser, audio player and image viewer for the ODROID-GO. I mainly use it to listen to music using the odroig-go headphone hat from the backofficeshow. You can checkout the Github Project and the forum post if you want to give it a try yourself. What follows is the history of its development until now. Hope you like it!
Ever since I received my ODROID-GO last year I had fun developing small programs for it. I like the challenge to write programs for embedded devices with limited resources. It forces you to understand much more about the hardware and software stack than the usual high level programming I’ve done.
One day I read a forum post by Cralex about [Feature/App Requests][forum-post] that mentions an on-device file manager and links to the 3DShell Project. The README of the project describes the purpose of 3DShell as follows:
3DShell (pronounced 3D-Shell) - is a multi-purpose file manager for the Nintendo 3DS that aims towards handling media files.
And so the idea for ogo-shell was born. It should be a file browser or manager that I can extend with more and more functionality like playing various media files.
Development until now
Because testing small program changes on the ODROID-GO takes some time I chose to implement the hardware related functions again using the SDL2 Library. (SDL2 is a popular C library used mostly in games and provides cross platform access to graphics, audio and input hardware.) That makes it possible to run ogo-shell locally on my computer so I can iterate quickly and debug the application logic more easily.
After implementing the simulation I began working on the file browser. I had already made an ftp server for the GO, so I was familiar with the file system APIs. The rover file browser for terminals served as an inspiration and also has very clean C code that was delightful to read. At this point I want to thank all the people out there that publish their work as open source. Only their efforts make it possible to develop projects like this one.
Once basic file browsing was done, I wanted to see how easy it would be to play various audio files. Getting them just to play was relatively easy but for an audio player that is convenient to use I faced some challenges.
One reason for that is concurrency. The player not only has to play music, reading your encoded music from the SD card but also react to your input while doing so. Implementing this nicely in C for both the simulation and the ODROID-GO was not easy, but made me learn more about mutexes, queues and how they work.
Another obstacle is the result of the ODROID-GOs hardware. The ESP32 in the ODROID-GO uses the same SPI connection to communicate with both the display and the SD card. That means you can’t update the display and read from the SD card at the same time. By patching the underlying SDK using a mutex I made sure that the program can’t access the SD card until the display is finished updating.
The rest was gluing together open source libraries that handled audio decoding and getting the user interface right. The player supports the usual MP3, OGG, FLAC and WAV audio formats. In addition to that it also support modules in the MOD, XM, IT and S3M formats. There is quite a big scene for music modules and a lot of nice tracks can be found on The Mod Archive.
The second version after the public release(0.3.0) includes a crude image viewer. It can only display small images though because of the small amount of RAM the ODROID-GO has. Let me explain why.
If you want to display a big image, let’s say one with the dimensions 1000x1000 pixels, the usual approach is to first decode the image file into memory and then resize it from there into another part of the memory. You can calculate the amount of space needed by multiplying the amount of pixels by the color depth of the image. Most images are using a color depth of 24-bit in the RGB format. That means we have three color channels for the colors red, green and blue and each channel is saved as an integer of 8 bits. To save our 1000x1000 image we then need 24 bits or 3 bytes multiplied by a million(1000 times 1000) which is already 3 million bytes. The amount of RAM you can easily access on ODROID-GO is 4 MB so anything much larger that 1000x1000 won’t fit into the memory. Since the usual approach doesn’t work one would have to come up with a more clever way of decoding only parts of the image and directly resizing it on the fly without the need of the large image buffer in RAM. These optimization can take a lot of effort that I didn’t want to spend on this project yet.
What I learnt is that getting a first prototype of a feature running is usually quite easy and fun. But polishing the software by fixing bugs, considering edge cases and adding quality of life features we take for granted usually takes much more time and effort and is not as fun. This is probably why there so much bugs in today’s software. The more complex your software gets the effort one has to invest to make it work perfectly.
I am currently working on support for chiptunes using the game-music-emu library that can emulate sound chips from old game consoles and computers. I really like the sound and creativity these old tunes have. What is also in the works is the ability to launch the go-play emulators from within ogo-shell. All in all, there are still lots of ideas for features to implement and bugs to fix.
That said is was quite fun to develop ogo-shell and learn new things while doing so. The satisfaction you get when you first see or hear your creation working as intended can be really addicting. I hope I have encouraged you to not only use programs but also learn to create new ones, and hope that ogo-shell may be useful to you.