Git Product home page Git Product logo

msu1_helper's Introduction

msu1_helper

Usage

Usage: msu1_helper [options]
    -i, --input-files=INPUT_FILES    input file or glob
    -t, --output-type=OUTPUT_TYPE    type to convert audio to (wav_pcm_s16le, msu1_pcm)
    -s, --loop-start=LOOP_START      sample number of where the loop should start
    -e, --loop-end=LOOP_END          sample number of where the loop should end
    -l, --loop-table=LOOP_TABLE      loop table filename
    -d, --destdir=DESTDIR            write converted files to this directory
    -h, --help                       show this message

High Level Explanation

If we have arbitrary audio files we want to use with the MSU-1 we need to do the following:

  1. Convert the audio into wav signed 16-bit little endian 44.1kHz. This new audio file will have the the same raw audio data that the MSU-1 can read, but it will have a wav header. This is OK because we need to be able to open this audio file up in some program that can inspect audio
  2. Use an audio program, preferably one that can show you sample numbers, to find the sample numbers of where you want the song to loop. Videogame songs, in general, loop seemlessly so you have to be able to find the sample numbers to get this effect. Since the audio is 44.1kHz there will be 44,100 samples per second. You can think of each sample representing 1/44100th of a second of data.
  3. Normalize the audio levels. I find -22 LUFS works well.
  4. With the loop start and end points we cut all the audio from the wav file after the loop point. We can then remove the wav header and replace it with the MSU-1 header which contains the loop start point (in little endian).

Bulk Conversion Example

starting with mp3 files

Suppose we start with a directory of mp3 files and we want to convert them for the MSU-1.

┌■ jcarson@burnt43 bar 
└% tree /home/jcarson/msu1_audio/foo/bar 
/home/jcarson/msu1_audio/foo/bar
└── mp3
    ├── 1 - Overworld Theme.mp3
    ├── 2 - Dungeon Theme.mp3
    └── 3 - Forest Theme.mp3

1 directory, 3 files

convert mp3 files to wav

We need to convert all these files to wav signed 16-bit little endian pcm. To do this we can run the following command:

┌■ jcarson@burnt43 msu1_helper git:master ●
└% ./msu1_helper.rb --input-files="/home/jcarson/msu1_audio/foo/bar/mp3/*.mp3" --output-type=wav_pcm_s16le --destdir="/home/jcarson/msu1_audio/foo/bar/wav"
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/mp3/0002_dungeon_theme.mp3 -acodec pcm_s16le /home/jcarson/msu1_audio/foo/bar/wav/0002_dungeon_theme.wav
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/mp3/0001_overworld_theme.mp3 -acodec pcm_s16le /home/jcarson/msu1_audio/foo/bar/wav/0001_overworld_theme.wav
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/mp3/0003_forest_theme.mp3 -acodec pcm_s16le /home/jcarson/msu1_audio/foo/bar/wav/0003_forest_theme.wav

We should now have the files in the mp3 directory renamed with a convention and now have converted files written into a wav directory

┌■ jcarson@burnt43 bar 
└% tree /home/jcarson/msu1_audio/foo/bar
/home/jcarson/msu1_audio/foo/bar
├── mp3
│   ├── 0001_overworld_theme.mp3
│   ├── 0002_dungeon_theme.mp3
│   └── 0003_forest_theme.mp3
└── wav
    ├── 0001_overworld_theme.wav
    ├── 0002_dungeon_theme.wav
    └── 0003_forest_theme.wav

2 directories, 6 files

use an audio editor/daw to find loop points

We can now open up the wav files in an audio editor or daw and find the sample numbers of where the loop should start and where the loop should end.

create loop table file

After finding the loop points we can create a loop table file that lists the files and the loop start and the loop end. It should look like the following:

0001_overworld_theme.wav,500_103, 2_340_100
0002_dungeon_theme.wav,140_346,1_567_890
0003_forest_theme.wav,0,44_100

The loop table maps files and their loop points

use loop table file to convert the wavs to something the MSU-1 can play

Now we can convert the wavs to pcm files that the MSU-1 can play. We can do that with the following command:

┌■ jcarson@burnt43 msu1_helper git:master ●
└% ./msu1_helper.rb --input-files="/home/jcarson/msu1_audio/foo/bar/wav/*.wav" --output-type=msu1_pcm --destdir="/home/jcarson/msu1_audio/foo/bar/pcm" --loop-table="/home/jcarson/msu1_audio/foo/bar/bar.lt"
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/wav/0001_overworld_theme.wav -af atrim=start_sample=0:end_sample=2340100 /home/jcarson/msu1_audio/foo/bar/pcm/0001_overworld_theme_trim.wav
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/pcm/0001_overworld_theme_trim.wav -f s16le -c:a pcm_s16le /home/jcarson/msu1_audio/foo/bar/pcm/0001_overworld_theme_trim.raw
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/wav/0003_forest_theme.wav -af atrim=start_sample=0:end_sample=44100 /home/jcarson/msu1_audio/foo/bar/pcm/0003_forest_theme_trim.wav
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/pcm/0003_forest_theme_trim.wav -f s16le -c:a pcm_s16le /home/jcarson/msu1_audio/foo/bar/pcm/0003_forest_theme_trim.raw
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/wav/0002_dungeon_theme.wav -af atrim=start_sample=0:end_sample=1567890 /home/jcarson/msu1_audio/foo/bar/pcm/0002_dungeon_theme_trim.wav
/usr/bin/ffmpeg -hide_banner -loglevel panic -y -i /home/jcarson/msu1_audio/foo/bar/pcm/0002_dungeon_theme_trim.wav -f s16le -c:a pcm_s16le /home/jcarson/msu1_audio/foo/bar/pcm/0002_dungeon_theme_trim.raw

We should now have a pcm directory with the files:

┌■ jcarson@burnt43 bar 
└% tree /home/jcarson/msu1_audio/foo/bar
/home/jcarson/msu1_audio/foo/bar
├── bar.lt
├── mp3
│   ├── 0001_overworld_theme.mp3
│   ├── 0002_dungeon_theme.mp3
│   └── 0003_forest_theme.mp3
├── pcm
│   ├── 0001_overworld_theme.pcm
│   ├── 0002_dungeon_theme.pcm
│   └── 0003_forest_theme.pcm
└── wav
    ├── 0001_overworld_theme.wav
    ├── 0002_dungeon_theme.wav
    └── 0003_forest_theme.wav

3 directories, 10 files

msu1_helper's People

Contributors

burnt43 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

msu1_helper's Issues

normalize volume levels

I made a song pack for ALTTPR using the converted Legacy of the Wizard files. I noticed the sound was louder than it should be.

I need to use ffmpeg to normalize. I've tested this in the command line OK.
sample for getting stats

ffmpeg -i ./02_warriors_theme.wav -af loudnorm=I=-20:TP=-5:LRA=11:print_format=json -f null -

sample for normalizing

ffmpeg -i ./02_warriors_theme.wav -af loudnorm=linear=true:I=-21:measured_I=-17.6:measured_TP=-2.1:measured_LRA=1.8:measured_thresh=-27.8:offset=0.1:print_format=json ./output.wav

I think the 'I' parameter to loudnorm is important here. This file was measured at -17.6, maybe trying -21 will work better

normalization sometimes inflates the file size

Compare the trimmed version of the file with the trimmed_normalized version of the file. In a working track like 0104 it is the same size, however in 0115 the file size is inflated and does not play correctly on the SNES. I think this is because certain tracks are getting upsampled to 192khz and I probably just need to force 44.1 khz output to fix this.

-rw-r--r-- 1 jcarson jcarson 16307160 May 12 21:10 0104_times_grasslands_home_world.pcm
-rw-r--r-- 1 jcarson jcarson 16307152 May 12 21:10 0104_times_grasslands_home_world_trimmed_normalized.raw
-rw-r--r-- 1 jcarson jcarson 16307346 May 12 21:10 0104_times_grasslands_home_world_trimmed_normalized.wav
-rw-r--r-- 1 jcarson jcarson 16307346 May 12 21:10 0104_times_grasslands_home_world_trimmed.wav
-rw-r--r-- 1 jcarson jcarson 70997136 May 12 21:09 0115_viper_manor.pcm
-rw-r--r-- 1 jcarson jcarson 70997128 May 12 21:09 0115_viper_manor_trimmed_normalized.raw
-rw-r--r-- 1 jcarson jcarson 70997366 May 12 21:09 0115_viper_manor_trimmed_normalized.wav
-rw-r--r-- 1 jcarson jcarson 16307366 May 12 21:09 0115_viper_manor_trimmed.wav

refactor

Things to Accomplish

  1. Use layout like I use in my current projects
  2. Think about using FileOperationChain and have them be separate objects that each do one specific thing on a file and return the filename to the next worker in the chain.
  3. comment code

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.