Source code for musical_games.converters.audio

from itertools import dropwhile
import tempfile
from musical_games.converters.utils import run_command, bash_function_exists, ensure_dir_exists, remove_file_if_exists

__author__ = 'Robbert Harms'
__date__ = "2015-09-22"
__maintainer__ = "Robbert Harms"
__email__ = "robbert.harms@maastrichtuniversity.nl"


[docs]def midi_to_wav(midi_fname, wav_fname, sound_font, gain=None): """Tries to autodetect the available midi converter and uses the best one found. Args: midi_fname (str): the location of the midi file wav_fname (str): where to place the output wav file. sound_font (str): the path to the sound font file. gain (float): number between 0 and 1 to indicate the desired output gain. """ converter = _get_first_available_converter([FluidSynth(sound_font, gain=gain), Timidity(sound_font, gain=gain)]) converter.convert(midi_fname, wav_fname)
[docs]def wav_to_mp3(wav_fname, mp3_fname): """Tries to autodetect the available wav converter and uses the best one found. Args: wav_fname (str): where to place the output wav file. mp3_fname (str): the path to the output mp3 file """ converter = _get_first_available_converter([FFMpeg(), AVConv()]) converter.to_mp3(wav_fname, mp3_fname)
[docs]def wav_to_ogg(wav_fname, ogg_fname): """Tries to autodetect the available wav converter and uses the best one found. Args: wav_fname (str): where to place the output wav file. ogg_fname (str): the path to the output mp3 file """ converter = _get_first_available_converter([FFMpeg(), AVConv()]) converter.to_ogg(wav_fname, ogg_fname)
def _get_first_available_converter(converters): if not any([converter.is_available() for converter in converters]): raise RuntimeError('No suitable converter found.') return next(dropwhile(lambda c: not c.is_available(), converters))
[docs]class MidiToWav(object): def __init__(self, sound_font, gain=None): """Create a new converter to convert midi to wav. Args: sound_font (str): the path to the sound font to use. gain (float): number between 0 and 1 to indicate the desired output gain. """ self._sound_font = sound_font self.gain = gain or 0.02
[docs] def convert(self, midi_fname, wav_fname): """Convert the given midi file to a wav file at the given location. Args: midi_fname (str): the location of the midi file wav_fname (str): where to place the output wav file. """
[docs] def is_available(self): """Check if the implementing method is available. Returns: bool: if this method is available """
[docs]class FluidSynth(MidiToWav):
[docs] def convert(self, midi_fname, wav_fname): ensure_dir_exists(wav_fname) run_command('fluidsynth -g {gain} -F {wav} {soundfont} {midi}'.format( wav=wav_fname, soundfont=self._sound_font, midi=midi_fname, gain=self.gain * 10))
[docs] def is_available(self): return bash_function_exists('fluidsynth')
[docs]class Timidity(MidiToWav):
[docs] def convert(self, midi_fname, wav_fname): ensure_dir_exists(wav_fname) with tempfile.NamedTemporaryFile('w') as tmp_file: tmp_file.write('soundfont {}'.format(self._sound_font)) tmp_file.flush() run_command('timidity -c {config} --output-24bit -A120 -Ow -o {wav} {midi}'.format( config=tmp_file.name, wav=wav_fname, midi=midi_fname))
[docs] def is_available(self): return bash_function_exists('timidity')
[docs]class WavConverter(object): """Converter for converting wav to any other media format."""
[docs] def to_mp3(self, wav_fname, output_fname): """Convert the given wav file to an mp3 file. Args: wav_fname (str): the wav filename output_fname (str): the output file """
[docs] def to_ogg(self, wav_fname, output_fname): """Convert the given wav file to an ogg file. Args: wav_fname (str): the wav filename output_fname (str): the output file """
[docs] def is_available(self): """Check if the implementing method is available. Returns: bool: if this method is available """
[docs]class FFMpegLike(WavConverter): def __init__(self, command_name): self.command_name = command_name
[docs] def to_mp3(self, wav_fname, output_fname): ensure_dir_exists(output_fname) remove_file_if_exists(output_fname) run_command('{command} -i {wav} -vn -ar 44100 -ac 2 -ab 192k -f mp3 {mp3}'.format( command=self.command_name, wav=wav_fname, mp3=output_fname))
[docs] def to_ogg(self, wav_fname, output_fname): ensure_dir_exists(output_fname) remove_file_if_exists(output_fname) run_command('{command} -i {wav} -acodec libvorbis {ogg}'.format( command=self.command_name, wav=wav_fname, ogg=output_fname))
[docs] def is_available(self): return bash_function_exists(self.command_name)
[docs]class FFMpeg(FFMpegLike): def __init__(self): super(FFMpeg, self).__init__('ffmpeg')
[docs]class AVConv(FFMpegLike): def __init__(self): super(AVConv, self).__init__('avconv')