撥子 [數位音樂] 用免費軟體將 MIDI 轉為 WAV 和 MP3

MIDI
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

說明

由於 MIDI 僅為音符而非聲音的記錄格式,播放 MIDI 音樂時會受到合成器及音源的影響而產生不同的樂音。所以,MIDI 不適合直接當成聲音檔傳給別人。現階段瀏覽器對播放 MIDI 的支援度也不好 (出處)。本文介紹將 MIDI 轉為 WAV 和 MP3 的方式。

將 MIDI 轉 WAV

安裝相關軟體

要將 MIDI 轉為 WAV,需要以下兩種東西:

  • 合成器 (synthesizer)
  • SoundFont

不論是在 Windows 還是 macOS,都可以用 FluidSynth 這套免費的軟體合成器將 MIDI 合成聲音檔。

Windows 使用者可到這裡下載預編好的 FluidSynth 最新穩定版本。將 FluidSynth 指令加入 PATH 變數即可。若不會改環境變數,可以看這篇文章

macOS 使用者則可使用 Homebrew 來安裝 FluidSynth:

$ brew install fluid-synth

除了合成器外,還需要搭配 SoundFont 才能將 MIDI 轉成 WAV。由於使用不同 SoundFont 會產生不同音色,選擇 SoundFont 是個人化的事情。有些 SoundFont 合出來的聲音比較和諧,有些則機械感過重。建議實際轉幾個 MIDI 檔案來聽,用耳朵感受合適的 SoundFont。

目前主流的 SoundFont 格式是 SoundFont 2,其副檔名是 .sf2 。建議找 general MIDI SoundFont,可以包含所有 MIDI 樂器的音色。目前 MIDI 樂器沒有國樂樂器,只能找發音原理相近的樂器來替代。這裡有一份 MIDI 樂器的清單

在 Windows 使用 FluidSynth

原本 FluidSynth 的指令長這個樣子:

$ fluidsynth -ni sound_font.sf2 input.mid -F output.wav -r 44100

每次都要重覆輸入一長串指令很不方便。我們把上述指令包裝如下:

$ midi2wav.bat file.midi

這個包裝後的指令,會自動生成檔名。以本例來說,輸入 file.midi 後會自動產生 file.wav 。此外,有些固定參數就直接寫在命令稿 (script) 裡,不需要重覆輸入。

Windows 版本的指令使用 Batch 命令稿來寫。其內容如下:

@echo off
rem midi2wav.bat
rem
rem Copyright (c) 2022 Four-String Mate. Licensed under MIT

rem Set custom parameters.
set soundFont=%USERPROFILE%\Documents\SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2
set sampleRate=44100

rem Check whether a sound font on the system.
if not exist %soundFont% (
    echo No sound font on the system
    exit /b 1
)

rem Check whether FluidSynth on the system.
fluidsynth --version 2>&1 1>nul || (
    echo No FluidSynth on the system
    exit /b 1
)

rem Check whether the argument is valid.
if not exist "%1" (
    echo Usage: %0 "path\to\file.[mid|midi]"
    exit /b 1
)

rem Extract some text from the argument.
set dirname=%~dp1
set filename=%~n1
set extension=%~x1

rem .midi is a valid file extension for MIDI.
if "%extension%" == ".midi" goto convert

rem .mid is a valid file extension for MIDI as well.
if "%extension%" == ".mid" goto convert

rem Other file formats are invalid.
echo Wrong file format: %extension%
exit /b 1

rem Convert a MIDI file to a WAV audio by FluidSynth.
:convert
fluidsynth -ni "%soundFont%" "%1" -F "%dirname%%filename%.wav" -r %sampleRate%

本文不是電腦教學,不詳細講每行指令的意義。只要根據自行需求修改參數 (parameters) 的地方,其他地方不需修改。

將該命令稿放在 PATH 所在的位置即可使用。撥子習慣將單一檔案指令放在 %USERPROFILE%\bin,像是 C:\Users\user\bin

在 macOS 使用 FluidSynth

承上,在 macOS 則改用 Bourne shell 寫這個命令稿。其內容如下:

#!/bin/sh
# midi2wav
#
# Copyright (c) 2022 Four-String Mate. Licensed under MIT

# Set custom parameters.
SOUND_FONT=$HOME/Documents/SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2
SAMPLE_RATE=44100

# Check whether a sound font on the system.
if ! [ -f "$SOUND_FONT" ]; then
    echo "No sound font on the system" >&2;
    exit 1;
fi

# Check whether FluidSynth on the system.
if ! command -v fluidsynth 2>&1 >/dev/null; then
    echo "No FluidSynth on the system" >&2;
    exit 1;
fi

# Check whether the argument is valid.
INPUT=$(realpath $1);
if ! [ -f "$INPUT" ]; then
    echo "Usage: $0 path/to/file.[mid/midi]" >&2;
    exit 1;
fi

# Extract some text from the argument.
DIRNAME=$(dirname "$INPUT");
FILENAME=$(basename "$INPUT" | sed 's/\(.*\)\..*/\1/');
EXTENSION=$(basename "$INPUT" | sed 's/.*\.\(.*\)/\1/');

# Convert a MIDI file to a WAV audio by FluidSynth.
if [ "$EXTENSION" = "mid" ] || [ "$EXTENSION" = "midi" ]; then
    fluidsynth -ni "$SOUND_FONT" "$INPUT" -F "$DIRNAME/$FILENAME.wav" -r $SAMPLE_RATE;
else
    echo "Wrong file format: $EXTENSION" >&2;
    exit 1;
fi

按照 Unix 的慣例,個人指令會放在 $HOME/bin,像是 macOS 的 /Users/user/bin

將 WAV 轉 MP3

WAV 是未壓縮格式,檔案會比較大。若想要減少檔案大小,可再將 WAV 轉成 MP3。

安裝 ffmpeg

Windows 使用者要 ffmpeg 官網下載預編好的指令即可使用。同樣要將 ffmpeg 的指令所在位置加入 PATH 變數。

macOS 使用者可利用 Homebrew 安裝 ffmpeg:

$ brew install ffmpeg

在 Windows 使用 ffmpeg

ffmpeg(1) 的指令如下:

$ ffmpeg -i input.wav -vn -ar 44100 -b:a 192k output.mp3

每次都要重覆輸入長指令比較麻煩。我們同樣用命令稿包裝該指令。包裝過的指令如下:

$ wav2mp3 file.wav

輸入 file.wav 會自動轉為 file.mp3 。常見參數直接寫進命令稿就可以了,不需要每次都重新輸入。

Windows 版本的命令稿用 Batch 來寫。其內容如下:

@echo off
rem wav2mp3.bat
rem
rem Copyright (c) 2022 Four-String Mate. Licensed under MIT

rem Set custom parameters.
set sampleRate=44100
set audioBitrate=192k

rem Check whether ffmpeg on the system.
ffmpeg -version 2>&1 1>nul || (
    echo No ffmpeg on the system
    exit /b 1
)

rem Check whether the argument is valid.
if not exist "%1" (
    echo Usage: %0 "path\to\file.wav"
    exit /b 1
)

rem Extract some text from the argument.
set dirname=%~dp1
set filename=%~n1
set extension=%~x1

rem .wav is a valid file extension for WAV audios.
if "%extension%" == ".wav" goto convert

rem Other file formats are invalid.
echo Wrong file format: %extension%
exit /b 1

rem Convert a WAV to a MP3 audio by ffmpeg.
:convert
ffmpeg -i "%1" -vn -ar %sampleRate% -b:a %audioBitrate% "%diranme%%filename%.mp3"

將該命令稿加到 PATH 所在的位置即可使用。

在 macOS 使用 ffmpeg

承上,在 macOS 則以 Bourne shell 來寫命令稿:

#!/bin/sh
# wav2mp3
#
# Copyright (c) 2022 Four-String Mate. Licensed under MIT

# Set custom parameters.
SAMPLE_RATE=44100
AUDIO_BITRATE=192k

# Check whether ffmpeg on the system.
if ! command -v ffmpeg 2>&1 >/dev/null; then
    echo "No ffmpeg on the system" >&2;
    exit 1;
fi

# Check whether the argument is valid.
INPUT=$(realpath $1);
if ! [ -f "$INPUT" ]; then
    echo "Usage: $0 path/to/file.wav" >&2;
    exit 1;
fi

# Extract some text from the argument.
DIRNAME=$(dirname "$INPUT");
FILENAME=$(basename "$INPUT" | sed 's/\(.*\)\..*/\1/');
EXTENSION=$(basename "$INPUT" | sed 's/.*\.\(.*\)/\1/');

# Convert a WAV to a MP3 audio by FluidSynth.
if [ "$EXTENSION" = "wav" ]; then
    ffmpeg -i "$INPUT" -vn -ar $SAMPLE_RATE -b:a $AUDIO_BITRATE "$DIRNAME/$FILENAME.mp3";
else
    echo "Wrong file format: $EXTENSION" >&2;
    exit 1;
fi

同上,將命令稿放到 PATH 所在的位置即可使用。

關於作者

撥子為資訊碩士及音樂愛好者,曾學習中阮、烏克麗麗、吉他、鋼琴等樂器。

除了對音樂的愛好,撥子喜歡黑咖啡和日本料理,會簡單的日文,有時會閱讀,有時會自助旅行。