This is an old revision of the document!
Cassette Tapes let you store a lot of information (from 1MB to 8MB, depending on the tape type). They also have the bonus benefit of letting you store audio in a special format… and play it back!
To read from, write to and play them back, you want to craft a Tape Drive.
Audio is written in a special format called DFPWM. As of right now, there are no easy-to-use solutions to convert regular MP3s and OGGs into this format.
LionRay is a tool by gamax92. It lets you convert WAV files into DFPWM-format data. Simply select the input and output filenames… and convert!
Download here - MIT license
LionRay is recommended nowadays due to having a better GUI and less bugs ~ asie
Wabbitoe is a tool which can convert .wav files into DFPWM. They must be 8- or 16-bit uncompressed PCM, and have a sane rate and channel count. It will do a nearest-neighbour resample, a simple truncation of any 16-bit audio data, and a simple mix of all the channels, so you should probably use SoX to do all the resampling for you. But it's easy to use - run the .jar, pick a .wav file to open, pick where and what to save the .dfpwm file as.
Download here - contains public-domain source code.
Grab these. These are compression and decompression software for DFPWM. aucmp takes a RAW, 8-bit signed audio stream as input and outputs DFPWM data, the reverse goes for audecmp. The rate of the stream is 32768Hz. Here's an example Linux shell script, where $1 is the input WAV file:
#!/bin/sh sox $1 -e signed-integer -b 8 -c 1 -r 32768 tmp.raw ./aucmp < tmp.raw > tmp.dfpwm ./audecmp < tmp.dfpwm > out.raw sox -e signed-integer -b 8 -c 1 -r 32768 out.raw out.wav
The script requires SoX - download here.
Use write(byte) to write audio data byte by byte. Read from the .dfpwm file to get the audio data you want to write. Each byte write advances the tape position by 1 byte - after you finish writing, use seek(-length) to go back to the beginning. To read a single byte, use read(). It will also advance the tape position.
|isReady()||0.1.0||Checks if a tape is inserted.||Returns true or false.|
|isEnd()||0.1.0||Checks if the tape is at most 0.25 seconds away from being over.||Returns true or false.|
|getSize()||0.1.0||Get the size of the tape.||Returns the tape size in bytes.|
|getLabel()||0.1.0||Get the tape's label.||Returns the tape's label.|
|getState()||0.2.1||Get the tape drive's state.||Returns “PLAYING”, “REWINDING”, “FORWARDING” or “STOPPED”.|
|setLabel(label)||0.1.0||Set the tape's label.||-|
|setSpeed(speed)||0.3.1||Set the tape's speed.||speed is a value from 0.25 to 2.0, denoting the difference from regular tape speed, which is 1.0.|
|setVolume(volume)||???||Set the volume of playback.||volume is a value from 0.0 to 1.0.|
|seek(amount)||0.1.0||Seek through the tape.||amount is the amount to seek in bytes, returns the amount of bytes actually seeked.|
|read()||0.1.0||Read a single byte from the tape.||Returns a byte.|
|write(byte)||0.1.0||Write a single byte to the tape.||byte - value from 0 to 255.|
|play(), stop()||0.1.0||Controls music playback.||-|
|0x00||Get the current state number.||Set the current state number.|
|0x04||Get the sound volume (0-127).||Set the sound volume (0-127).|
|0x06||Get the current tape length, in minutes (one minute is 4096*60 bytes).||-|
|0x08||Return the amount of bytes seeked.||Seek a number of bytes.|
|0x0A||Read one byte.||Write one byte.|