Module music_df.conversions.ms3
A function, ms3_to_df(), for converting ms3 dfs to the format used by this package.
Functions
def ms3_to_df(ms3_df: pandas.DataFrame,
measures_df: pandas.DataFrame | None,
remove_zero_duration_notes: bool = True,
drop_first_endings: bool = True,
fractions: bool = True,
drop_unused_cols: bool = True) ‑> pandas.DataFrame-
Expand source code
def ms3_to_df( ms3_df: pd.DataFrame, measures_df: pd.DataFrame | None, remove_zero_duration_notes: bool = True, drop_first_endings: bool = True, fractions: bool = True, drop_unused_cols: bool = True, ) -> pd.DataFrame: """ Convert an ms3 dataframe to the format used by this package. """ out_df = ms3_df.copy() if "quarterbeats_playthrough" in out_df.columns: # This means the repeats are expanded pass elif drop_first_endings: out_df = out_df[~out_df["quarterbeats"].isna()].reset_index(drop=True) if measures_df is not None: if "quarterbeats" in measures_df.columns: measures_df = measures_df[ ~measures_df["quarterbeats"].isna() ].reset_index(drop=True) else: raise NotImplementedError _handle_times(out_df, fractions) if "name" in out_df.columns: # remove last character of "name" column (A4 -> A, etc.) out_df["spelling"] = out_df["name"].str[:-1] else: # earlier versions of ms3 don't seem to have the name column but # we can get the spelling from the "tpc" column out_df["spelling"] = out_df["tpc"].apply(tpc2name) # rename some columns out_df.rename(columns={"midi": "pitch", "staff": "part"}, inplace=True) # add "tie_to_next" boolean column true if "tied" is in (0, 1) out_df["tie_to_next"] = out_df["tied"].isin((0, 1)) out_df["tie_to_prev"] = out_df["tied"].isin((0, -1)) if remove_zero_duration_notes: # If there are any zero-duration notes (grace notes?), drop them out_df = out_df[out_df["onset"] != out_df["release"]] out_df["type"] = "note" out_df = _add_time_sigs(out_df) if measures_df is None: LOGGER.warning( """Inferring barlines won't give correct results when there is an empty measure or when a measure begins with a rest. Use the `measures.tsv` files provided in the ABC corpora if possible.""" ) out_df = _infer_bars(out_df) elif ( "quarterbeats" not in measures_df.columns and "quarterbeats_playthrough" not in measures_df.columns ): LOGGER.warning( """`measures_df` is missing "quarterbeats" column and can't be used.""" ) out_df = _infer_bars(out_df) else: _handle_times(measures_df, fractions) out_df = _add_bars_from_measures_df(out_df, measures_df) if drop_unused_cols: return_columns = [ "pitch", "onset", "release", "tie_to_next", "tie_to_prev", "voice", "part", "spelling", "type", "other", ] out_df = out_df[return_columns] return sort_df(out_df)Convert an ms3 dataframe to the format used by this package.
def remap_time_column(x)-
Expand source code
remap_time_column = lambda x: Fraction(x).limit_denominator(DENOM_LIMIT) def tpc2name(tpc: int, minor: bool = False) ‑> str-
Expand source code
def tpc2name(tpc: int, minor: bool = False) -> str: """Turn a tonal pitch class (TPC) into a name or perform the operation on a collection of integers. >>> tpc2name(-1) 'F' >>> tpc2name(-1, minor=True) 'f' >>> tpc2name(-8, minor=True) 'fb' >>> tpc2name(6) 'F#' >>> tpc2name(13) 'F##' Based on equivalent function from MS3. Args: tpc: Tonal pitch class(es) to turn into a note name. minor: Pass True if the string is to be returned as lowercase. Returns: """ note_names = MINOR_NOTE_NAMES if minor else NOTE_NAMES acc, ix = divmod(tpc + 1, 7) acc_str = abs(acc) * "b" if acc < 0 else acc * "#" return f"{note_names[ix]}{acc_str}"Turn a tonal pitch class (TPC) into a name or perform the operation on a collection of integers.
>>> tpc2name(-1) 'F' >>> tpc2name(-1, minor=True) 'f' >>> tpc2name(-8, minor=True) 'fb' >>> tpc2name(6) 'F#' >>> tpc2name(13) 'F##'Based on equivalent function from MS3.
Args
tpc- Tonal pitch class(es) to turn into a note name.
minor- Pass True if the string is to be returned as lowercase.
Returns: