Пример #1
0
def get_music(a, b, key='C', mode='major'):
    midi_out = StringIO()

    scale = build_scale(key, mode, octaves=1)
    matcher = SequenceMatcher(None, a, b)

    tone = key.lower()
    melodies = [tone]
    for tag, i1, i2, j1, j2 in matcher.get_opcodes():
        next_note = None
        if tag == 'replace':
            next_note = 'r'
        elif tag == 'equal':
            next_note = tone
        elif tag == 'delete':
            tone = tone_down(tone, scale)
            next_note = tone
        elif tag == 'insert':
            tone = tone_up(tone, scale)
            next_note = tone
        melodies += [next_note] * ((i2 - i1) or 1)
    s = SMF([parse(" ".join(melodies))])

    s.write(midi_out)
    return midi_out
Пример #2
0
    def test_write_midi_multi_tacks(self):
        """
        Writing out test.mid to ensure midi processing works.

        This isn't really a test.
        """
        from sebastian.core import OSequence, Point
        from sebastian.core import OFFSET_64, MIDI_PITCH, DURATION_64
        test1 = OSequence([
            Point({OFFSET_64: o, MIDI_PITCH: m, DURATION_64: d}) for (o, m, d) in [
                (0, 60, 16), (16, 72, 16), (32, 64, 16), (48, 55, 16),
            ]
        ])
        test2 = OSequence([
            Point({OFFSET_64: o, MIDI_PITCH: m, DURATION_64: d}) for (o, m, d) in [
                (0, 55, 16), (16, 55, 16), (32, 64, 16), (48 + 16, 55, 16 * 10),
            ]
        ])

        from sebastian.midi.write_midi import SMF
        from io import BytesIO
        out_fd = BytesIO(bytearray())

        expected_bytes = b"""MThd\x00\x00\x00\x06\x00\x01\x00\x03\x00\x10MTrk\x00\x00\x00&\x00\xffX\x04\x04\x02\x18\x08\x00\xffY\x02\x00\x00\x00\xffQ\x03\x07\xa1 \x00\xff\x03\ttest song\x00\xff/\x00MTrk\x00\x00\x00'\x00\xc0\x00\x00\x90<@\x10\x80<\x00\x00\x90H@\x10\x80H\x00\x00\x90@@\x10\x80@\x00\x00\x907@\x10\x807\x00\x00\xff/\x00MTrk\x00\x00\x00(\x00\xc1\x10\x00\x917@\x10\x817\x00\x00\x917@\x10\x817\x00\x00\x91@@\x10\x81@\x00\x10\x917@\x81 \x817\x00\x00\xff/\x00"""
        s = SMF([test1, test2], instruments=[0, 16])
        s.write(out_fd, title="test song")
        actual_bytes = out_fd.getvalue()

        self.assertEqual(expected_bytes, actual_bytes)
Пример #3
0
    def test_write_midi(self):
        """
        Writing out test.mid to ensure midi processing works.

        This isn't really a test.
        """

        from sebastian.core import OSequence, Point
        from sebastian.core import OFFSET_64, MIDI_PITCH, DURATION_64
        test = OSequence([
            Point({OFFSET_64: o, MIDI_PITCH: m, DURATION_64: d}) for (o, m, d) in [
                (0, 60, 16), (16, 72, 16), (32, 64, 16), (48, 55, 16),
                (64, 74, 16), (80, 62, 16), (96, 50, 16), (112, 48, 16),
                (128, 36, 16), (144, 24, 16), (160, 40, 16), (176, 55, 16),
                (192, 26, 16), (208, 38, 16), (224, 50, 16), (240, 48, 16)
            ]
        ])

        from sebastian.midi.write_midi import SMF
        from io import BytesIO
        out_fd = BytesIO(bytearray())

        expected_bytes = b'MThd\x00\x00\x00\x06\x00\x01\x00\x02\x00\x10MTrk\x00\x00\x00%\x00\xffX\x04\x04\x02\x18\x08\x00\xffY\x02\x00\x00\x00\xffQ\x03\x07\xa1 \x00\xff\x03\x08untitled\x00\xff/\x00MTrk\x00\x00\x00\x87\x00\xc0\x00\x00\x90<@\x10\x80<\x00\x00\x90H@\x10\x80H\x00\x00\x90@@\x10\x80@\x00\x00\x907@\x10\x807\x00\x00\x90J@\x10\x80J\x00\x00\x90>@\x10\x80>\x00\x00\x902@\x10\x802\x00\x00\x900@\x10\x800\x00\x00\x90$@\x10\x80$\x00\x00\x90\x18@\x10\x80\x18\x00\x00\x90(@\x10\x80(\x00\x00\x907@\x10\x807\x00\x00\x90\x1a@\x10\x80\x1a\x00\x00\x90&@\x10\x80&\x00\x00\x902@\x10\x802\x00\x00\x900@\x10\x800\x00\x00\xff/\x00'

        s = SMF([test], instruments=None)
        s.write(out_fd)
        actual_bytes = out_fd.getvalue()

        self.assertEqual(expected_bytes, actual_bytes)
Пример #4
0
def separate_files():
    for num, pattern in enumerate(patterns):
        sequence = parse(pattern)
        f = open("in_c_%s.mid" % (num + 1), "w")
        s = SMF([sequence])
        s.write(f)
        f.close()
Пример #5
0
    def test_velocity_from_note_with_invalid_velocities(self):
        from sebastian.core import OSequence, Point
        from sebastian.core import OFFSET_64, MIDI_PITCH, DURATION_64

        test = OSequence([
            Point({
                OFFSET_64: o,
                MIDI_PITCH: m,
                DURATION_64: d
            }) for (o, m, d) in [(0, 60, 16), (16, 72, 16), (32, 64, 16)]
        ])

        test[0]['velocity'] = -1
        test[1]['velocity'] = 300

        from sebastian.midi.write_midi import SMF
        from io import BytesIO
        out_fd = BytesIO(bytearray())

        expected_bytes = b'MThd\x00\x00\x00\x06\x00\x01\x00\x02\x00\x10MTrk\x00\x00\x00&\x00\xffX\x04\x04\x02\x18\x08\x00\xffY\x02\x00\x00\x00\xffQ\x03\x07\xa1 \x00\xff\x03\ttest song\x00\xff/\x00MTrk\x00\x00\x00\x1f\x00\xc0\x00\x00\x90<\x00\x10\x80<\x00\x00\x90H\xff\x10\x80H\x00\x00\x90@@\x10\x80@\x00\x00\xff/\x00'

        s = SMF([test])
        s.write(out_fd, title="test song")
        actual_bytes = out_fd.getvalue()

        self.assertEqual(expected_bytes, actual_bytes)
Пример #6
0
def one_file():
    seq = OSequence([])
    for num, pattern in enumerate(patterns):
        seq = seq + parse(pattern) * 10
    f = open("in_c_all.mid", "w")
    s = SMF([seq])
    s.write(f)
    f.close()
Пример #7
0
def performance():
    tracks = []
    for track_num in range(8):  # 8 tracks
        seq = OSequence([])
        for pattern in patterns:
            seq += parse(pattern) * random.randint(2, 5)  # repeat 2-5 times
        tracks.append(seq | transpose(random.choice([-12, 0, 12])))  # transpose -1, 0 or 1 octaves
    f = open("in_c_performance.mid", "w")
    s = SMF(tracks)
    s.write(f)
    f.close()
Пример #8
0
    def test_write_midi(self):
        """
        Writing out test.mid to ensure midi processing works.

        This isn't really a test.
        """

        from sebastian.core import OSequence, Point
        from sebastian.core import OFFSET_64, MIDI_PITCH, DURATION_64
        test = OSequence([
            Point({
                OFFSET_64: o,
                MIDI_PITCH: m,
                DURATION_64: d
            })
            for (o, m,
                 d) in [(0, 60,
                         16), (16, 72,
                               16), (32, 64,
                                     16), (48, 55,
                                           16), (64, 74,
                                                 16), (80, 62,
                                                       16), (96, 50,
                                                             16), (112, 48,
                                                                   16),
                        (128, 36,
                         16), (144, 24,
                               16), (160, 40,
                                     16), (176, 55,
                                           16), (192, 26,
                                                 16), (208, 38,
                                                       16), (224, 50,
                                                             16), (240, 48,
                                                                   16)]
        ])

        from sebastian.midi.write_midi import SMF
        from io import BytesIO
        out_fd = BytesIO(bytearray())

        expected_bytes = b'MThd\x00\x00\x00\x06\x00\x01\x00\x02\x00\x10MTrk\x00\x00\x00%\x00\xffX\x04\x04\x02\x18\x08\x00\xffY\x02\x00\x00\x00\xffQ\x03\x07\xa1 \x00\xff\x03\x08untitled\x00\xff/\x00MTrk\x00\x00\x00\x87\x00\xc0\x00\x00\x90<@\x10\x80<\x00\x00\x90H@\x10\x80H\x00\x00\x90@@\x10\x80@\x00\x00\x907@\x10\x807\x00\x00\x90J@\x10\x80J\x00\x00\x90>@\x10\x80>\x00\x00\x902@\x10\x802\x00\x00\x900@\x10\x800\x00\x00\x90$@\x10\x80$\x00\x00\x90\x18@\x10\x80\x18\x00\x00\x90(@\x10\x80(\x00\x00\x907@\x10\x807\x00\x00\x90\x1a@\x10\x80\x1a\x00\x00\x90&@\x10\x80&\x00\x00\x902@\x10\x802\x00\x00\x900@\x10\x800\x00\x00\xff/\x00'

        s = SMF([test], instruments=None)
        s.write(out_fd)
        actual_bytes = out_fd.getvalue()

        self.assertEqual(expected_bytes, actual_bytes)
Пример #9
0
    def test_write_midi_multi_tacks(self):
        """
        Writing out test.mid to ensure midi processing works.

        This isn't really a test.
        """
        from sebastian.core import OSequence, Point
        from sebastian.core import OFFSET_64, MIDI_PITCH, DURATION_64
        test1 = OSequence([
            Point({
                OFFSET_64: o,
                MIDI_PITCH: m,
                DURATION_64: d
            }) for (o, m, d) in [
                (0, 60, 16),
                (16, 72, 16),
                (32, 64, 16),
                (48, 55, 16),
            ]
        ])
        test2 = OSequence([
            Point({
                OFFSET_64: o,
                MIDI_PITCH: m,
                DURATION_64: d
            }) for (o, m, d) in [
                (0, 55, 16),
                (16, 55, 16),
                (32, 64, 16),
                (48 + 16, 55, 16 * 10),
            ]
        ])

        from sebastian.midi.write_midi import SMF
        from io import BytesIO
        out_fd = BytesIO(bytearray())

        expected_bytes = b"""MThd\x00\x00\x00\x06\x00\x01\x00\x03\x00\x10MTrk\x00\x00\x00&\x00\xffX\x04\x04\x02\x18\x08\x00\xffY\x02\x00\x00\x00\xffQ\x03\x07\xa1 \x00\xff\x03\ttest song\x00\xff/\x00MTrk\x00\x00\x00'\x00\xc0\x00\x00\x90<@\x10\x80<\x00\x00\x90H@\x10\x80H\x00\x00\x90@@\x10\x80@\x00\x00\x907@\x10\x807\x00\x00\xff/\x00MTrk\x00\x00\x00(\x00\xc1\x10\x00\x917@\x10\x817\x00\x00\x917@\x10\x817\x00\x00\x91@@\x10\x81@\x00\x10\x917@\x81 \x817\x00\x00\xff/\x00"""
        s = SMF([test1, test2], instruments=[0, 16])
        s.write(out_fd, title="test song")
        actual_bytes = out_fd.getvalue()

        self.assertEqual(expected_bytes, actual_bytes)
Пример #10
0
    def test_velocity_from_note_with_invalid_velocities(self):
        from sebastian.core import OSequence, Point
        from sebastian.core import OFFSET_64, MIDI_PITCH, DURATION_64

        test = OSequence([
            Point({OFFSET_64: o, MIDI_PITCH: m, DURATION_64: d}) for (o, m, d) in [
                (0, 60, 16), (16, 72, 16), (32, 64, 16)
            ]
        ])

        test[0]['velocity'] = -1
        test[1]['velocity'] = 300

        from sebastian.midi.write_midi import SMF
        from io import BytesIO
        out_fd = BytesIO(bytearray())

        expected_bytes = b'MThd\x00\x00\x00\x06\x00\x01\x00\x02\x00\x10MTrk\x00\x00\x00&\x00\xffX\x04\x04\x02\x18\x08\x00\xffY\x02\x00\x00\x00\xffQ\x03\x07\xa1 \x00\xff\x03\ttest song\x00\xff/\x00MTrk\x00\x00\x00\x1f\x00\xc0\x00\x00\x90<\x00\x10\x80<\x00\x00\x90H\xff\x10\x80H\x00\x00\x90@@\x10\x80@\x00\x00\xff/\x00'

        s = SMF([test])
        s.write(out_fd, title="test song")
        actual_bytes = out_fd.getvalue()

        self.assertEqual(expected_bytes, actual_bytes)
Пример #11
0
#!/usr/bin/env python

from sebastian.lilypond.interp import parse
from sebastian.midi.write_midi import SMF

rh = parse(r"""
    \relative c'' {
        g16 fis g8 ~ g16 d16 e fis g a b cis
        d16 cis d8 ~ d16 a16 b cis d e fis d
        g16 fis g8 ~ g16 fis16 e d cis e a, g
        fis e d cis d fis a, g fis a d,8
    }""")

lh = parse(r"""
    \relative c {
        g8 b'16 a b8 g g, g'
        fis,8 fis'16 e fis8 d fis, d'
        e,8 e'16 d e8 g a, cis'
        d, fis16 e fis8 d d,
    }""")

# operator overloading FTW!
seq = rh // lh

if __name__ == "__main__":
    f = open("var1.mid", "w")
    s = SMF([seq])
    s.write(f)
    f.close()
Пример #12
0
def get_music(series, key='C', mode='major', octaves=2,
              instruments=None, period=12):
    '''
    Returns music generated from an inserted series.

    Parameters
    ----------
    series : an array that could be an 2d-array.

    key : Musical key.
        Can be setted as a parameter while building scale.
        Key should be written as "C", for C and "C#" for C sharp and
        "Cb" for C flat.

    mode : Music mode.
        'major', 'minor' and 'pentatonic' are accetable parameters.
        More options of modes on `build_scale`.

    octaves : Number of available scales for musical construction.
        As higher are the octaves higher pitch differeneces will occur
        while representing your data.

    instruments : list of MIDI instruments.
        General MIDI Level 1 Instrument Patch Map can be found at:
        http://en.wikipedia.org/wiki/General_MIDI
        Gran Piano is the default usage value '[0]' if any instruments
        are declared.
        Fewer examples:
        [0] Acoustic Grand Piano
        [18] Rock Organ
        [23] Tango Accordion
        [32] Acoustic Bass
        [73] Flute

    period : int
        parameter of chord_scaled function.

    Returns
    -------
    midi_out : BytesIO object.
        It can be written on a file or used by your way.

    Example
    -------
    >>> data = np.random.random(10).reshape(2,5)
    array([[ 0.13536875,  0.42212475,  0.26360219,  0.30153336,  0.62150923],
       [ 0.49384405,  0.32503762,  0.85549822,  0.80212442,  0.70702405]])

    >>> get_music(data, octaves=2, instruments=(0,23))
    <io.BytesIO instance at 0x7f98201c9d40>

    '''
    midi_out = BytesIO()

    series = np.array(series)
    scale = build_scale(key, mode, octaves)
    melodies = []
    if len(series.shape) == 1:
        if all(np.isnan(series)):
            melody = []
            melodies.append(melody)
        else:
            snotes = note_number(series, scale)
            melody = parse(' '.join([note_name(x, scale) for x in snotes]))
            melodies.append(melody)
    else:
        for i in range(series.shape[0]):
            if all(np.isnan(series[i])):
                melody = []
                melodies.append(melody)
            else:
                snotes = note_number(series[i], scale)
                melody = parse(' '.join([note_name(x, scale) for x in snotes]))
                melodies.append(melody)
        
            # chords = chord_scaled(series, scale, period)
            # Transform it to a MIDI file with chords.
            # s = SMF([melody, chords], instruments=[0, 23])
    if instruments is None:
        s = SMF(melodies)
    else:
        s = SMF(melodies, instruments)

    s.write(midi_out)
    return midi_out