virtual USB
contents
background
My car (Opel Astra tourer) has a radio (the "infotainment system") with a USB connector. You can put an USB device in it and it can then play the MP3 files on it. Really nice but there's a catch though: the car radio has a 1000 songs limit. This sounds like a lot but after a few weeks they start to repeat and that gets annoying. Of course I could manually swap the USB stick but "oh the hassle".
The car looks like this (a bit: mine is blue):
The Opel also has an audio-in connector but when I connect my phone to it, the sound quality is horrible. The Opel is too old for streaming over blue tooth unfortunately.
the solution
I read that the Raspberry Pi Zero has a "USB gadget mode". This mode allows it to pretend it is a device of some kind (webcam, Ethernet adapter, etc). One of the devices it can emulate is a storage device like a regular USB stick!
The RPI zero I use is just a regular one:
details
In this USB gadget mode, it can emulate a storage device. Via a Linux kernel module called "g_mass_storage" you can serve a disk-image to the USB-host (= the device you connect your USB stick or raspberry pi zero to) as if it was a real USB stick. Of course there is still the 1000 songs limit with my car but to work around that I created a script for it which chooses an image at random and feeds that to "g_mass_storage". The only things left are making sure to mount the RPI Zero SD-card read-only so that I can just switch of my car without the proper Linux shutdown procedure and the other thing is a script which automatically produces disk-image-files from a bunch of MP3 files.
implementation
here you'll find the script that picks at random a disk-image file (from the /home/pi/images directory on the RPI Zero SD card) and configures up the Linux kernel gadget mode with it. Important thing in that script is that it produces a serial number unique for the image file. Else the car may not detect the virtual disk being replaced by an other. Run this script from /etc/rc.local or a systemd service. Also make sure to add 'dtoverlay=dwc2' to /boot/config.txt and 'dwc2' to /etc/modules.
And this script collects MP3-files from a directory (including subdirectories) and copies that to one or more disk-images. It needs to be run as root because it uses loopback devices. There may be a different way for doing this but for the proof of concept this is good enough. It shall be invoked like:
sudo ./create-images.py ~/Musicwhere all mp3 files are in ~/Music and the resulting image00000... are stored in the current directory. It needs the "parted" and "mkfs.vfat" programs which are in the 'parted' and 'dosfstools' packages (at least in Debian).

future improvements
Future improvements will be:
- improve the bootproces; it takes about a minute for the RPI to boot
- 3D print an enclosure for the RPI Zero
- connect a button or rotary button switch to it for skipping or maybe selecting a specific image
- create an alternative kernel module which generates a disk-image on the fly from a bunch of files instead of the route of image-files
similar projects
I've been pointed at this project which is basically the same and does not require you to create disk-images. I have not tested it.