Module hierarchical_quantifier.reader
This module is used to read MIDI format files in a file system and convert it to a sampled pitchscape representation.
Expand source code
"""
This module is used to read MIDI format files in a file system and
convert it to a sampled pitchscape representation.
"""
import pitchscapes.reader as rd
import numpy as np
import os
from multiprocessing import Pool
from hierarchical_quantifier.utils import read_pickle, write_pickle, check_pickle_argument
from music21.midi import MidiException
from itertools import repeat
import warnings
def read_file(file_path: str, resolution: int = 100, pickle=False, force_reset=False) -> np.ndarray:
"""
Read a MIDI format file and convert to a pitchscape representation. Note that if a file from the
file list is not convertable, it will be ignored in the return object.
:param file_path: path to a MIDI file.
:param resolution: number of time bins used to sample the MIDI file.
:param pickle: Read from pickle file if true.
:param force_reset: Write the data if true.
:type file_path: str
:type resolution: int
:type pickle: bool
:type force_reset: bool
:return: sampled pitchscape representation of the given MIDI file.
:rtype numpy.ndarray of shape (resolution, 12)
"""
if (type(file_path) != str) and (type(file_path) != np.str_):
raise TypeError('file_path must be a string.')
if file_path == '':
raise ValueError('File path empty.')
if not os.path.isfile(file_path):
raise FileNotFoundError('File path not found.')
if resolution <= 0:
raise ValueError('Resolution must be hiher than 0')
count = None
pickle_filename = __pickle_filename(file_path, resolution)
if pickle:
count = read_pickle(pickle_filename)
if not count is None:
return count
try:
count = rd.sample_density_with_pitchscape(resolution, scape=rd.get_pitch_scape(file_path))
if force_reset:
write_pickle(pickle_filename, count)
return count
except MidiException:
raise ValueError(file_path + ' file is corrupted.')
def read_file_array(file_paths: list, resolution: int=100, force_reset=False,
pickle=False) -> np.ndarray: # ignore_errors flag
"""
Read a list of MIDI format file and convert each one of them to a pitchscape representation.
:param pickle: read the pickle file.
:param force_reset: write as a pickle file.
:param file_paths: list of MIDI file paths. The list is of size m.
:param resolution: number of time bins used to sample the MIDI file.
:type: file_paths: list
:type: resolution: int
:return: sampled pitchscape representation of the given MIDI files.
:rtype: numpy.ndarray of shape (m, resolution, 12)
"""
if len(file_paths) == 0:
raise ValueError('filepaths is empty.')
check_pickle_argument(pickle, force_reset)
file_paths = np.asarray(file_paths)
ret = read_pickle(pickle)
if not ret is None:
return ret
ret = []
with Pool(5) as p:
ret = p.starmap(read_file,zip(file_paths,repeat(resolution)))
'''
for f in file_paths:
try:
ret.append(read_file(f, resolution))
except ValueError:
warnings.warn(f + ' is not readable.')
'''
ret = np.asarray(ret)
write_pickle(force_reset, ret)
return ret
def __pickle_filename(filepath, resolution):
filename = os.path.basename(filepath)
filename_no_extension = os.path.splitext(filename)[0]
res_text = '_RES_' + str(resolution) + '.pkl'
return os.path.join('./', filename_no_extension + res_text)
Functions
def read_file(file_path: str, resolution: int = 100, pickle=False, force_reset=False) ‑> numpy.ndarray
-
Read a MIDI format file and convert to a pitchscape representation. Note that if a file from the file list is not convertable, it will be ignored in the return object.
:param file_path: path to a MIDI file. :param resolution: number of time bins used to sample the MIDI file. :param pickle: Read from pickle file if true. :param force_reset: Write the data if true. :type file_path: str :type resolution: int :type pickle: bool :type force_reset: bool :return: sampled pitchscape representation of the given MIDI file. :rtype numpy.ndarray of shape (resolution, 12)
Expand source code
def read_file(file_path: str, resolution: int = 100, pickle=False, force_reset=False) -> np.ndarray: """ Read a MIDI format file and convert to a pitchscape representation. Note that if a file from the file list is not convertable, it will be ignored in the return object. :param file_path: path to a MIDI file. :param resolution: number of time bins used to sample the MIDI file. :param pickle: Read from pickle file if true. :param force_reset: Write the data if true. :type file_path: str :type resolution: int :type pickle: bool :type force_reset: bool :return: sampled pitchscape representation of the given MIDI file. :rtype numpy.ndarray of shape (resolution, 12) """ if (type(file_path) != str) and (type(file_path) != np.str_): raise TypeError('file_path must be a string.') if file_path == '': raise ValueError('File path empty.') if not os.path.isfile(file_path): raise FileNotFoundError('File path not found.') if resolution <= 0: raise ValueError('Resolution must be hiher than 0') count = None pickle_filename = __pickle_filename(file_path, resolution) if pickle: count = read_pickle(pickle_filename) if not count is None: return count try: count = rd.sample_density_with_pitchscape(resolution, scape=rd.get_pitch_scape(file_path)) if force_reset: write_pickle(pickle_filename, count) return count except MidiException: raise ValueError(file_path + ' file is corrupted.')
def read_file_array(file_paths: list, resolution: int = 100, force_reset=False, pickle=False) ‑> numpy.ndarray
-
Read a list of MIDI format file and convert each one of them to a pitchscape representation.
:param pickle: read the pickle file. :param force_reset: write as a pickle file. :param file_paths: list of MIDI file paths. The list is of size m. :param resolution: number of time bins used to sample the MIDI file. :type: file_paths: list :type: resolution: int :return: sampled pitchscape representation of the given MIDI files. :rtype: numpy.ndarray of shape (m, resolution, 12)
Expand source code
def read_file_array(file_paths: list, resolution: int=100, force_reset=False, pickle=False) -> np.ndarray: # ignore_errors flag """ Read a list of MIDI format file and convert each one of them to a pitchscape representation. :param pickle: read the pickle file. :param force_reset: write as a pickle file. :param file_paths: list of MIDI file paths. The list is of size m. :param resolution: number of time bins used to sample the MIDI file. :type: file_paths: list :type: resolution: int :return: sampled pitchscape representation of the given MIDI files. :rtype: numpy.ndarray of shape (m, resolution, 12) """ if len(file_paths) == 0: raise ValueError('filepaths is empty.') check_pickle_argument(pickle, force_reset) file_paths = np.asarray(file_paths) ret = read_pickle(pickle) if not ret is None: return ret ret = [] with Pool(5) as p: ret = p.starmap(read_file,zip(file_paths,repeat(resolution))) ''' for f in file_paths: try: ret.append(read_file(f, resolution)) except ValueError: warnings.warn(f + ' is not readable.') ''' ret = np.asarray(ret) write_pickle(force_reset, ret) return ret