Example #1
0
 def __post_init__(self):
     stream = music21.converter.parse(self.data)
     self.xml = stream_to_xml(stream)
     self.notes = [
         Note(n.offset, n.offset + n.duration.quarterLength, n.pitch.ps, i)
         for i, n in enumerate(indexers.NotePointSet(stream))
     ]
     self.windows = list(generate_normalized_windows(stream, WINDOW))
Example #2
0
 def __post_init__(self):
     self.music21_xml = symbolic_data_to_m21_xml(self.data)
     stream = music21.converter.parse(self.music21_xml)
     self.notes = [
         piece.Note(n.offset, n.offset + n.duration.quarterLength,
                    n.pitch.ps, i)
         for i, n in enumerate(indexers.NotePointSet(stream))
     ]
Example #3
0
 def __post_init__(self):
     stream = music21.converter.parse(base64.b64decode(self.data))
     stream.makeNotation(inPlace=True)
     xml = m21_score_to_xml_write(stream)
     self.data = xml
     self.notes = [
         Note(n.offset, n.offset + n.duration.quarterLength, n.pitch.ps, i)
         for i, n in enumerate(indexers.NotePointSet(stream))
     ]
Example #4
0
def generate_normalized_windows(stream, window_size):
    notes = [
        Note(n.offset, n.offset + n.duration.quarterLength, n.pitch.ps, i)
        for i, n in enumerate(indexers.NotePointSet(stream))
    ]

    for i in range(min(len(notes) - window_size + 1, len(notes))):
        window = notes[i:i + window_size]
        bases = [(window[0], window[i]) for i in range(1, len(window))]
        for u, v in ((u, v) for u, v in bases if u.onset != v.onset):
            yield (u, v), normalize(window, (u, v))
Example #5
0
def search():
    db_conn = connect_to_psql()

    for arg in (x.name for x in fields(QueryArgs)):
        missing = []
        if not request.args.get(arg):
            missing.append(arg)
        if missing:
            return Response(f"Missing GET parameter(s): {missing}", status=400)

    try:
        page = int(request.args.get("page"))
        rpp = int(request.args.get("rpp"))
        tnps = request.args.get("tnps").split(",")
        tnps_ints = list(map(int, tnps))
        tnps_ints[1] += 1  # increase range to include end
        intervening = request.args.get("intervening").split(",")
        intervening_ints = tuple(map(int, intervening))
        inexact = request.args.get("inexact").split(",")
        inexact_ints = tuple(map(int, inexact))
        collection = int(request.args.get("collection"))
        query_str = request.args.get("query")
        qargs = QueryArgs(rpp, page, tnps, intervening, inexact, collection,
                          query_str)
    except ValueError as e:
        return Response(
            f"Failed to parse parameter(s) to integer, got exception {str(e)}",
            status=400)

    query_str = request.args.get("query")
    query_stream = indexers.parse(query_str)
    query_nps = indexers.NotePointSet(query_stream)
    query_notes = [(n.offset, n.pitch.ps) for n in query_nps]
    query_pb_notes = [
        piece.Note(n[0], None, n[1], i).to_pb()
        for i, n in enumerate(query_notes)
    ]
    resp = requests.get(POSTGREST_URI + "/rpc/search",
                        params=('query=' + qstring(query_pb_notes))).json()
    occurrences = [occurrence.occ_to_occpb(occ) for occ in resp]

    occfilters = OccurrenceFilters(transpositions=range(*tnps_ints),
                                   intervening=intervening_ints,
                                   inexact=inexact_ints)

    search_response = build_response(
        db_conn, filter_occurrences(occurrences, query_pb_notes, occfilters),
        qargs)

    if request.content_type == "application/json":
        return jsonify(search_response)
    else:
        return render_template("search.html", searchResponse=search_response)
Example #6
0
def query(stream):
    m = []
    query_length = len(indexers.NotePointSet(stream))
    for (u, v), window in generate_normalized_windows(stream, query_length):
        print(window)
        matches = {}
        for n in window:
            postings = BINS.get(n.__hash__(), ())
            for (u, v), j in postings:
                key = (u, v)
                matches[key] = matches.get(key, (u, )) + ((j, n.index), )
        m.append(matches)
    return set((c[key]) for c in m for key in c if len(c[key]) >= query_length)
def pointset(filename, outname):
    """
    Converts a musicxml file to its point set image representation
    """
    st = music21.converter.parse(filename)
    nps = indexers.NotePointSet(st)

    offsets = np.array([n.offset for n in nps])
    pitches = np.array([n.pitch.ps for n in nps])
    pointset_plot = plt.scatter(offsets, pitches)

    plt.xlabel("Quarter-length offset")
    plt.ylabel("Chromatic pitch")
    plt.savefig(outname)
Example #8
0
def query_postgres(stream):
    conn = psycopg2.connect("")
    matches = {}
    query_length = len(indexers.NotePointSet(stream))
    (u, v), window = next(generate_normalized_windows(stream, query_length))
    with conn, conn.cursor() as cur:
        for n in window:
            cur.execute(
                f"SELECT * FROM Posting WHERE n ~= '{(n.onset, n.pitch)}'")
            postings = cur.fetchall()
            for _, _, pid, u, v, j in postings:
                key = (pid, u, v)
                matches[key] = matches.get(key, (u, )) + ((j, n.index), )

    return set(v for v in matches.values() if len(v) >= query_length)
def pointsets(filenames, outname):
    fig, ax = plt.subplots()
    colours = cycle(('#a50000', '#00a500', '#0000a5'))
    for label, filename, colour in zip(filenames[::2], filenames[1::2],
                                       colours):
        st = music21.converter.parse(filename)
        nps = indexers.NotePointSet(st)
        offsets = np.array([n.offset for n in nps])
        pitches = np.array([n.pitch.ps for n in nps])
        ax.scatter(offsets, pitches, c=colour, label=label)
    ax.legend()
    ax.grid(True)
    plt.xlabel("Quarter-length offset")
    plt.ylabel("Chromatic pitch")
    fig.savefig(outname)