Example #1
0
def chord_scaled(arr, scale, period=12):
    '''
    Scales an note's array
    '''
    remainder = arr.size % period
    if remainder:
        fill = period - remainder
        arr = np.append(arr, np.zeros(fill) * np.nan)

    arr_scaled = np.int32([np.nansum(row) / len(row)
                           for row in arr.reshape((-1, period))])

    root_scaled = [note_on_classes(note, arr, scale) for note in arr_scaled]
    root = []
    third = []
    fifth = []
    for note in root_scaled:
        root.append(note_name(note, scale))
        third.append(note_name(note, scale))
        fifth.append(note_name(note, scale))

    seq1 = parse(" ".join(root))
    seq2 = parse(" ".join(third))
    seq3 = parse(" ".join(fifth))

    # chords = (seq1 * period) // (seq2 * period) // (seq3 * period)
    chords = seq1 // seq2 // seq3
    # return (chords | add({DURATION_64: chords[0][DURATION_64] * period}))
    return (chords | stretch(period))
Example #2
0
 def play_rand_song_uno(self, counts=20):
     alpha = parse(self.gen_rand_snippet(counts))
     beta = parse(self.gen_rand_snippet(counts))
     gamma = parse(self.gen_rand_snippet(counts))
     delta = parse(self.gen_rand_snippet(counts))
     player.play([alpha, beta])
     player.play([alpha, gamma])
     player.play([beta, gamma])
     player.play([alpha])
Example #3
0
    def eq(self, lilypond, answer):
        """ The first is a lilypond fragment. The second is
        the intended interpretation, a sequence of (offset, pitch, duration) tuples
        where offset and duration are in multiples of a 64th note and pitch is MIDI
        note number.
        """

        print "\nTEST: %s" % lilypond
        result = parse(lilypond)
        i = -1  # so available in else clause of for
        for i, event in enumerate(answer):
            r = result[i].tuple(OFFSET_64, MIDI_PITCH, DURATION_64)
            if event != r:
                print "%s != %s" % (event, r)
                print "\x1B[31mFAIL\x1B[0m"
                break
            else:
                print "%s == %s" % (event, r)
        else:
            if len(answer) != len(result):
                print "\x1B[31mFAIL (different length)\x1B[0m"
                for j in range(i + 1, len(result)):
                    print "!= %s" % (result[j].tuple(OFFSET_64, MIDI_PITCH, DURATION_64), )
            else:
                print "\x1B[32mSUCCESS\x1B[0m"
Example #4
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
Example #5
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()
Example #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()
Example #7
0
 def eq(self, lilypond, answer):
     """ The first is a lilypond fragment. The second is
     the intended interpretation, a sequence of (offset, pitch, duration) tuples
     where offset and duration are in multiples of a 64th note and pitch is MIDI
     note number.
     """
     result = parse(lilypond)
     self.assertEqual(len(answer), len(result))
     for i, event in enumerate(answer):
         r = result[i].tuple(OFFSET_64, MIDI_PITCH, DURATION_64)
         self.assertEqual(event, r)
Example #8
0
def deduce_rosetta_stone():
    octave = parse("c cis d dis e f fis g gis a ais b") | midi_to_pitch()
    pitches = []
    try:
        for point in octave:
            print point
            pitches.append(point['pitch'])
        #pitches = [point['pitch'] for point in octave]
    except Exception as e:
        pass
        return pitches
Example #9
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()
Example #10
0
 def eq(self, lilypond, answer):
     """ The first is a lilypond fragment. The second is
     the intended interpretation, a sequence of (offset, pitch, duration) tuples
     where offset and duration are in multiples of a 64th note and pitch is MIDI
     note number.
     """
     result = parse(lilypond)
     self.assertEqual(len(answer), len(result))
     for i, event in enumerate(answer):
         r = result[i].tuple(OFFSET_64, MIDI_PITCH, DURATION_64)
         self.assertEqual(event, r)
Example #11
0
    def play_music(self, x, y):
        '''
        Generate sounds from data to be used for each coordinate.
        x and y are the coordinates of any image point.
        '''
        scale = build_scale('C', mode='major', octaves=1)
        notes = note_number(self.data, scale)
        note = notes[y,x]

        melody = parse(note_name(note, scale))
        midi_out = StringIO()
        write('Oc.midi', [melody])

        os.system('fluidsynth --audio-driver=alsa /usr/share/sounds/sf2/FluidR3_GM.sf2 Oc.midi')
Example #12
0
    def play_music(self, x, y):
        '''
        Generate sounds from data to be used for each coordinate.
        x and y are the coordinates of any image point.
        '''
        scale = build_scale('C', mode='major', octaves=1)
        notes = note_number(self.data, scale)
        note = notes[y,x]

        melody = parse(note_name(note, scale))
        midi_out = StringIO()
        write('Oc.midi', [melody])

        pygame.mixer.init()

        music = pygame.mixer.Sound('Oc.midi')
        pygame.mixer.music.load('Oc.midi')
        pygame.mixer.music.play()
Example #13
0
def test(lilypond, answer):
    print "\nTEST: %s" % lilypond
    result = parse(lilypond)
    i = -1 # so available in else clause of for
    for i, event in enumerate(answer):
        r = result[i].tuple(OFFSET_64, MIDI_PITCH, DURATION_64)
        if event != r:
            print "%s != %s" % (event, r)
            print "\x1B[31mFAIL\x1B[0m"
            break
        else:
            print "%s == %s" % (event, r)
    else:
        if len(answer) != len(result):
            print "\x1B[31mFAIL (different length)\x1B[0m"
            for j in range(i + 1, len(result)):
                print "!= %s" % (result[j].tuple(OFFSET_64, MIDI_PITCH, DURATION_64), )
        else:
            print "\x1B[32mSUCCESS\x1B[0m"
Example #14
0
#!/usr/bin/env python

from sebastian.lilypond.interp import parse
from sebastian.lilypond.write_lilypond import write
from sebastian.midi import write_midi, player
from sebastian.core import OSequence, HSeq, Point, DURATION_64
from sebastian.core.transforms import transpose, reverse, add, degree_in_key, midi_pitch, lilypond
from sebastian.core.notes import Key, major_scale

# construct sequences using lilypond syntax
seq1 = parse("c d e")
seq2 = parse("e f g")

# concatenate
seq3 = seq1 + seq2

# transpose and reverse
seq4 = seq3 | transpose(12) | reverse()

# merge
seq5 = seq3 // seq4

# play MIDI
player.play([seq5])

# write to MIDI
write_midi.write("seq5.mid", [seq5])

# contruct a horizontal sequence of scale degrees
seq6 = HSeq(Point(degree=degree) for degree in [1, 2, 3, 2, 1])
Example #15
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
Example #16
0
#!/usr/bin/env python
"""
Generate ode to joy in the entire dynamic range "pppppp" -> "ffff". Also generate a crescendo from "ppp" to "ff" and a dimininuendo from "mf" to "ppp".

This will output numerous midi files, as well as three lilypond (*.ly) files with dynamic notation.
"""

from sebastian.lilypond.interp import parse
from sebastian.core.transforms import dynamics, lilypond, midi_to_pitch, add
from sebastian.midi import write_midi
from sebastian.lilypond import write_lilypond

# construct sequences using lilypond syntax
melody = parse("e4 e f g g f e d c c d e")
A = parse("e4. d8 d2")
Aprime = parse("d4. c8 c2")

two_bars = melody + A + melody + Aprime
two_bars = two_bars | midi_to_pitch()
two_bars = two_bars | add({"octave": 5})

velocities = [
    "pppppp", "ppppp", "pppp", "ppp", "pp", "p", "mp", "mf", "f", "ff", "fff",
    "ffff"
]

for d in velocities:
    two_bars_with_dynamics = two_bars | dynamics(d)
    write_midi.write("ode_%s.mid" % (d, ), [two_bars_with_dynamics])

two_bars_ff_lily = two_bars | dynamics("ff") | lilypond()
Example #17
0
#!/usr/bin/env python
"""
Generate ode to joy in the entire dynamic range "pppppp" -> "ffff". Also generate a crescendo from "ppp" to "ff" and a dimininuendo from "mf" to "ppp".

This will output numerous midi files, as well as three lilypond (*.ly) files with dynamic notation.
"""

from sebastian.lilypond.interp import parse
from sebastian.core.transforms import dynamics, lilypond, midi_to_pitch, add
from sebastian.midi import write_midi
from sebastian.lilypond import write_lilypond

# construct sequences using lilypond syntax
melody = parse("e4 e f g g f e d c c d e")
A = parse("e4. d8 d2")
Aprime = parse("d4. c8 c2")

two_bars = melody + A + melody + Aprime
two_bars = two_bars | midi_to_pitch()
two_bars = two_bars | add({"octave": 5})

velocities = ["pppppp", "ppppp", "pppp", "ppp", "pp", "p", "mp", "mf", "f", "ff", "fff", "ffff"]

for d in velocities:
    two_bars_with_dynamics = two_bars | dynamics(d)
    write_midi.write("ode_%s.mid" % (d,), [two_bars_with_dynamics])

two_bars_ff_lily = two_bars | dynamics("ff") | lilypond()
write_lilypond.write("ode_ff.ly", two_bars_ff_lily)

crescendo = two_bars | dynamics("ppp", "ff")
Example #18
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()
Example #19
0
#!/usr/bin/env python

from sebastian.lilypond.interp import parse
from sebastian.lilypond.write_lilypond import write
from sebastian.midi import write_midi, player
from sebastian.core import OSequence, HSeq, Point, DURATION_64
from sebastian.core.transforms import transpose, reverse, add, degree_in_key, midi_pitch, lilypond
from sebastian.core.notes import Key, major_scale

# construct sequences using lilypond syntax
seq1 = parse("c d e")
seq2 = parse("e f g")

# concatenate
seq3 = seq1 + seq2

# transpose and reverse
seq4 = seq3 | transpose(12) | reverse()

# merge
seq5 = seq3 // seq4

# play MIDI
player.play([seq5])

# write to MIDI
write_midi.write("seq5.mid", [seq5])

# contruct a horizontal sequence of scale degrees
seq6 = HSeq(Point(degree=degree) for degree in [1, 2, 3, 2, 1])
Example #20
0
#!/usr/bin/env python

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

# construct sequences using lilypond syntax
seq1 = parse("e4. d c r")
seq2 = parse("g4. f4 f8 e4.")
seq2a = parse("r4.")
seq2b = parse("r4 g8")
seq3 = parse("c'4 c'8 b a b c'4 g8 g4")
seq3a = parse("g8")
seq3b = parse("f8")

# concatenate
mice = (seq1 * 2) + (seq2 + seq2a) + (seq2 + seq2b) + (
    (seq3 + seq3a) * 2) + (seq3 + seq3b) + seq1

# write to MIDI
write_midi.write("mice.mid", [mice])
Example #21
0
 def play_rand_song_dos(self, counts=20):
     alpha = parse(self.gen_rand_snippet(counts))
     beta = parse(self.gen_rand_snippet(counts))
     gamma = parse(self.gen_rand_snippet(counts))
     delta = parse(self.gen_rand_snippet(counts))
     player.play([alpha+(alpha//beta)+(alpha//beta//gamma)+(alpha//beta//gamma//delta)])