Advertisement
osmarks

generate-tape-image.py

Dec 24th, 2019
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.21 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # generate-tape-image.py
  3. # Turns a directory of audio files into a single tape image with metadata.
  4. # Usage: python3 generate-tape-image.py [directory of audio files].
  5. # The filenames need to have the format `[artist] - [track name].[extension]`.
  6. # If you don't want this, you can edit the code for `process_file` and `process_dir` or something.
  7. # LionRay must be saved as "LionRay.jar" in the script's working directory.
  8. # The script produces a `tape.bin` file in its working directory.
  9. # This is suitable for writing directly to tapes using web2tape (https://pastebin.com/LW9RFpmY) if you have a webserver to upload to. Please make sure to give your tapes a unique label using the `tape label [whatever]` command.
  10. # Ensure that your `tape.bin` file is small enough to fit on whatever tape you're using. For example, a 32 minute tape is 11.52MB. You can check its filesize on Linux using `du -h tape.bin`. If it's not, remove tracks or reduce the sample rate of the WAV file ffmpeg generates (will reduce quality, and also not currently implemented - you will also want the tracks' metadata to contain a higher `speed` value so they get played faster to compensate).
  11. # If you have no file host thing you can use, I can't really help you, sorry about that. There are probably public ones.
  12. # Tape Shuffler (https://pastebin.com/SPyr8jrh) is the program which can play random tracks off these generated tape images.
  13.  
  14. import subprocess
  15. import tempfile
  16. import os
  17. import os.path
  18. import collections
  19. import json
  20. import sys
  21.  
  22. ProcessedTrack = collections.namedtuple("ProcessedTrack", ["dfpwm_file", "artist", "track"])
  23.  
  24. def convert_wav_dfpwm(infile, outfile):
  25.     subprocess.run(["java", "-jar", "LionRay.jar", infile, outfile])
  26.  
  27. def convert_any_wav(infile, outfile):
  28.     subprocess.run(["ffmpeg", "-hide_banner", "-i", infile, "-ac", "1", outfile], stderr=subprocess.PIPE)
  29.  
  30. def process_file(filename):
  31.     parts = list(map(str.strip, os.path.splitext(os.path.basename(filename))[0].split("-")))
  32.     artist = parts[0]
  33.     track = parts[1]
  34.     wav_dest = tempfile.mktemp(".wav")
  35.     convert_any_wav(filename, wav_dest)
  36.     dfpwm_dest = tempfile.mktemp(".dfpwm")
  37.     convert_wav_dfpwm(wav_dest, dfpwm_dest)
  38.     os.remove(wav_dest)
  39.     return ProcessedTrack(dfpwm_dest, artist, track)
  40.  
  41. def read_binary(filename):
  42.     with open(filename, "rb") as f:
  43.         return f.read()
  44.  
  45. def process_dir(dirname):
  46.     tracks = []
  47.     for file in os.listdir(dirname):
  48.         tracks.append(process_file(os.path.join(dirname, file)))
  49.     tape_image = b""
  50.     tracks_meta = []
  51.     for track in tracks:
  52.         track_meta = {}
  53.         track_meta["start"] = len(tape_image) + 8193
  54.         data = read_binary(track.dfpwm_file)
  55.         os.remove(track.dfpwm_file)
  56.         track_meta["end"] = track_meta["start"] + len(data)
  57.         track_meta["artist"] = track.artist
  58.         track_meta["title"] = track.track
  59.         tape_image += data
  60.         tracks_meta.append(track_meta)
  61.         print(track.track, track.artist)
  62.     meta = json.dumps({ "tracks": tracks_meta }).encode("utf-8").ljust(8192, b"\0")
  63.     tape_image = meta + tape_image
  64.     with open("tape.bin", "wb") as f:
  65.         f.write(tape_image)
  66.  
  67. process_dir(sys.argv[1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement