# Path: note_seq/audio_io.py
# class AudioIOError(BaseException):  # pylint:disable=g-bad-exception-name
# class AudioIOReadError(AudioIOError):
# class AudioIODataTypeError(AudioIOError):
# def int16_samples_to_float32(y):
# def float_samples_to_int16(y):
# def wav_data_to_samples_pydub(wav_data: bytes,
#                               sample_rate: int,
#                               remove_dc_bias: bool = False,
#                               num_channels: int = None,
#                               normalize_db: float = None):
# def wav_data_to_samples(wav_data, sample_rate):
# def wav_data_to_samples_librosa(audio_file, sample_rate):
# def samples_to_wav_data(samples, sample_rate):
# def crop_samples(samples, sample_rate, crop_beginning_seconds,
#                  total_length_seconds):
# def repeat_samples_to_duration(samples, sample_rate, duration):
# def crop_wav_data(wav_data, sample_rate, crop_beginning_seconds,
#                   total_length_seconds):
# def jitter_wav_data(wav_data, sample_rate, jitter_seconds):
# def load_audio(audio_filename, sample_rate):
# def make_stereo(left, right):
# def normalize_wav_data(wav_data, sample_rate, norm=np.inf):
# 
# Path: note_seq/midi_io.py
# _PRETTY_MIDI_MAJOR_TO_MINOR_OFFSET = 12
# class MIDIConversionError(Exception):
# def midi_to_note_sequence(midi_data):
# def midi_file_to_note_sequence(midi_file):
# def note_sequence_to_midi_file(sequence, output_file,
#                                drop_events_n_seconds_after_last_note=None):
# def note_sequence_to_pretty_midi(
#     sequence, drop_events_n_seconds_after_last_note=None):
# def midi_to_sequence_proto(midi_data):
# def sequence_proto_to_pretty_midi(sequence,
#                                   drop_events_n_seconds_after_last_note=None):
# def midi_file_to_sequence_proto(midi_file):
# def sequence_proto_to_midi_file(sequence, output_file,
#                                 drop_events_n_seconds_after_last_note=None):


import os
import align_fine_lib
from absl import app
from absl import flags
from absl import logging
from note_seq import audio_io
from note_seq import midi_io
flags.DEFINE_string(
    'log', 'INFO',
    'The threshold for what messages will be logged: '
    'DEBUG, INFO, WARN, ERROR, or FATAL.')


def main(unused_argv):
  logging.set_verbosity(FLAGS.log)
  if not os.path.exists(FLAGS.output_dir):
    os.makedirs(FLAGS.output_dir)
  for input_file in sorted(os.listdir(FLAGS.input_dir)):
    if not input_file.endswith('.wav'):
      continue
    wav_filename = input_file
    midi_filename = input_file.replace('.wav', '.mid')
    logging.info('Aligning %s to %s', midi_filename, wav_filename)

    samples = audio_io.load_audio(
        os.path.join(FLAGS.input_dir, wav_filename), align_fine_lib.SAMPLE_RATE)
    ns = midi_io.midi_file_to_sequence_proto(
        os.path.join(FLAGS.input_dir, midi_filename))

    aligned_ns, unused_stats = align_fine_lib.align_cpp(
        samples,
        align_fine_lib.SAMPLE_RATE,
        ns,
        align_fine_lib.CQT_HOP_LENGTH_FINE,
        sf2_path=FLAGS.sf2_path,
        penalty_mul=FLAGS.penalty_mul)


# Path: note_seq/audio_io.py
# class AudioIOError(BaseException):  # pylint:disable=g-bad-exception-name
# class AudioIOReadError(AudioIOError):
# class AudioIODataTypeError(AudioIOError):
# def int16_samples_to_float32(y):
# def float_samples_to_int16(y):
# def wav_data_to_samples_pydub(wav_data: bytes,
#                               sample_rate: int,
#                               remove_dc_bias: bool = False,
#                               num_channels: int = None,
#                               normalize_db: float = None):
# def wav_data_to_samples(wav_data, sample_rate):
# def wav_data_to_samples_librosa(audio_file, sample_rate):
# def samples_to_wav_data(samples, sample_rate):
# def crop_samples(samples, sample_rate, crop_beginning_seconds,
#                  total_length_seconds):
# def repeat_samples_to_duration(samples, sample_rate, duration):
# def crop_wav_data(wav_data, sample_rate, crop_beginning_seconds,
#                   total_length_seconds):
# def jitter_wav_data(wav_data, sample_rate, jitter_seconds):
# def load_audio(audio_filename, sample_rate):
# def make_stereo(left, right):
# def normalize_wav_data(wav_data, sample_rate, norm=np.inf):
# 
# Path: note_seq/midi_io.py
# _PRETTY_MIDI_MAJOR_TO_MINOR_OFFSET = 12
# class MIDIConversionError(Exception):
# def midi_to_note_sequence(midi_data):
# def midi_file_to_note_sequence(midi_file):
# def note_sequence_to_midi_file(sequence, output_file,
#                                drop_events_n_seconds_after_last_note=None):
# def note_sequence_to_pretty_midi(
#     sequence, drop_events_n_seconds_after_last_note=None):
# def midi_to_sequence_proto(midi_data):
# def sequence_proto_to_pretty_midi(sequence,
#                                   drop_events_n_seconds_after_last_note=None):
# def midi_file_to_sequence_proto(midi_file):
# def sequence_proto_to_midi_file(sequence, output_file,
#                                 drop_events_n_seconds_after_last_note=None):


# Path: note_seq/alignment/align_fine.py
import os
import align_fine_lib
from absl import app
from absl import flags
from absl import logging
from note_seq import audio_io
from note_seq import midi_io

flags.DEFINE_string(
    'log', 'INFO',
    'The threshold for what messages will be logged: '
    'DEBUG, INFO, WARN, ERROR, or FATAL.')


def main(unused_argv):
  logging.set_verbosity(FLAGS.log)
  if not os.path.exists(FLAGS.output_dir):
    os.makedirs(FLAGS.output_dir)
  for input_file in sorted(os.listdir(FLAGS.input_dir)):
    if not input_file.endswith('.wav'):
      continue
    wav_filename = input_file
    midi_filename = input_file.replace('.wav', '.mid')
    logging.info('Aligning %s to %s', midi_filename, wav_filename)

    samples = audio_io.load_audio(
        os.path.join(FLAGS.input_dir, wav_filename), align_fine_lib.SAMPLE_RATE)
    ns = midi_io.midi_file_to_sequence_proto(
        os.path.join(FLAGS.input_dir, midi_filename))

    aligned_ns, unused_stats = align_fine_lib.align_cpp(
        samples,
        align_fine_lib.SAMPLE_RATE,
        ns,
        align_fine_lib.CQT_HOP_LENGTH_FINE,
        sf2_path=FLAGS.sf2_path,
        penalty_mul=FLAGS.penalty_mul)


    midi_io.sequence_proto_to_midi_file(