def csv_to_miditime(self, infile, outfile, octave):
        raw_data = list(self.read_csv(infile))

        mymidi = MIDITime(self.tempo, outfile, self.seconds_per_year, self.base_octave, self.octave_range, self.epoch)

        note_list = []

        for r in raw_data:
            began_date = datetime.strptime(r["began_date"], "%Y-%m-%d %H:%M:%S+00:00")  # 2009-01-15 16:15:00+00:00
            ended_date = datetime.strptime(r["ended_date"], "%Y-%m-%d %H:%M:%S+00:00")

            began_days_since_epoch = mymidi.days_since_epoch(began_date)
            ended_days_since_epoch = mymidi.days_since_epoch(ended_date)

            start_beat = mymidi.beat(began_days_since_epoch)
            end_beat = mymidi.beat(ended_days_since_epoch)
            duration_in_beats = end_beat - start_beat

            if duration_in_beats < 3:
                duration_in_beats = 3
            # print start_beat, duration_in_beats
            note_list = note_list + self.bigger_boat(round(start_beat), duration_in_beats, mymidi, octave)

        # Add a track with those notes
        mymidi.add_track(note_list)

        # Output the .mid file
        mymidi.save_midi()
    def csv_to_miditime(self, infile, outfile, octave):
        raw_data = list(self.read_csv(infile))

        mymidi = MIDITime(self.tempo, outfile, self.seconds_per_year,
                          self.base_octave, self.octave_range, self.epoch)

        note_list = []
        start_note_index = 0

        for r in raw_data:
            began_date = datetime.strptime(
                r["began_date"],
                "%Y-%m-%d %H:%M:%S+00:00")  # 2009-01-15 16:15:00+00:00
            ended_date = datetime.strptime(r["ended_date"],
                                           "%Y-%m-%d %H:%M:%S+00:00")

            began_days_since_epoch = mymidi.days_since_epoch(began_date)
            ended_days_since_epoch = mymidi.days_since_epoch(ended_date)

            start_beat = mymidi.beat(began_days_since_epoch)
            end_beat = mymidi.beat(ended_days_since_epoch)
            duration_in_beats = end_beat - start_beat

            # if duration_in_beats < 3:
            #     duration_in_beats = 3
            # print start_beat, duration_in_beats
            new_notes, start_note_index = self.bigger_boat_2(
                start_beat, start_note_index, duration_in_beats, mymidi,
                octave)
            note_list = note_list + new_notes

        # Add a track with those notes
        mymidi.add_track(note_list)

        # Output the .mid file
        mymidi.save_midi()
def midify(sumsinearray):
    counter = 0
    global mymidi
    for i in range(len(sumsinearray)):
        name = str(sumsinearray[i][1]) +'.mid'
        mymidi = MIDITime(120, name, 4, 5, 1)
        my_data = dictify(sumsinearray[i][0])
        my_data_timed = [{'beat': mymidi.beat(d['datapoint']), 'magnitude': d['magnitude']} for d in my_data]
        start_time = my_data_timed[0]['beat']
        note_list = builtnotelist(my_data_timed, start_time)
    # Add a track with those notes
        mymidi.add_track(note_list)
    # Output the .mid file
        mymidi.save_midi()
        counter += 1
climate_data = []
with open('GLB.Ts+dSST.csv') as csvfile:
    readCSV = csv.reader(csvfile, delimiter=',')
    # skip headers (first 2 rows)
    next(readCSV)
    next(readCSV)
    for row in readCSV:
        climate_data.append({
            'days_since_epoch':
            mymidi.days_since_epoch(datetime.strptime(row[0], '%Y')),
            'magnitude_change':
            row[17]
        })

my_data_timed = [{
    'beat': mymidi.beat(d['days_since_epoch']),
    'magnitude_change': float(d['magnitude_change'])
} for d in climate_data]
start_time = my_data_timed[0]['beat']
data_list = [d['magnitude_change'] for d in my_data_timed]


def mag_to_pitch_tuned(magnitude):
    """
    Consumes some magnitude value and normalizes it over the range of note
    values provided from a key.
    :param magnitude: some int or float value representing magnitude of data
    :return: a MIDI pitch represented by the normalized value
    """
    # Where does this data point sit in the domain of your data?
    #(I.E. the min magnitude is 3, the max in 5.6). In this case the optional
class Coal2Midi(object):
    ''' Adapted from Jordan Wirfs-Brock's awesome coal production sonification.
    Post here: http://insideenergy.org/2016/05/03/listen-to-u-s-coal-production-fall-off-a-cliff/
    Code and data here: https://github.com/InsideEnergy/Data-for-stories/tree/master/20160503-coal-production-sonification
    '''

    epoch = datetime(1970, 1, 1)  # TODO: Allow this to override the midtime epoch
    mymidi = None

    tempo = 120

    min_attack = 30
    max_attack = 255

    min_duration = 1
    max_duration = 5

    seconds_per_year = 26

    c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
    c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb']
    a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#']
    c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb']
    d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']
    c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb']

    current_key = c_major
    base_octave = 4
    octave_range = 3

    def __init__(self):
        self.csv_to_miditime()

    def read_csv(self, filepath):
        csv_file = open(filepath, 'rU')
        return csv.DictReader(csv_file, delimiter=',', quotechar='"')

    def remove_weeks(self, csv_obj):
        return [r for r in csv_obj if int(r['Week']) not in [53]]

    def round_to_quarter_beat(self, input):
        return round(input * 4) / 4

    def round_to_half_beat(self, input):
        return round(input * 2) / 2

    def make_notes(self, data_timed, data_key):
        note_list = []

        start_time = data_timed[0]['beat']

        for d in data_timed:
            note_list.append([
                # self.round_to_half_beat(d['beat'] - start_time),
                round(d['beat'] - start_time),
                self.data_to_pitch_tuned(d[data_key]),
                100,
                #mag_to_attack(d['magnitude']),  # attack
                1  # duration, in beats
            ])
        return note_list

    def data_to_pitch_tuned(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        # Another option: Linear scale, reverse order
        # scale_pct = mymidi.linear_scale_pct(0, self.maximum, datapoint, True)

        # Another option: Logarithmic scale, reverse order
        # scale_pct = mymidi.log_scale_pct(0, self.maximum, datapoint, True)

        # Pick a range of notes. This allows you to play in a key.
        mode = self.current_key

        #Find the note that matches your data point
        note = self.mymidi.scale_to_note(scale_pct, mode)

        #Translate that note to a MIDI pitch
        midi_pitch = self.mymidi.note_to_midi_pitch(note)

        return midi_pitch

    def mag_to_attack(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        #max_attack = 10

        adj_attack = (1 - scale_pct) * max_attack + 70
        #adj_attack = 100

        return adj_attack

    def csv_to_miditime(self):
        self.mymidi = MIDITime(self.tempo, 'coaltest.mid', self.seconds_per_year, self.base_octave, self.octave_range)
        raw_data = self.read_csv('data/coal_prod_1984_2016_weeks_summed.csv')
        filtered_data = self.remove_weeks(raw_data)

        self.minimum = self.mymidi.get_data_range(filtered_data, 'CoalProd')[0] / 1000000.0
        self.maximum = self.mymidi.get_data_range(filtered_data, 'CoalProd')[1] / 1000000.0

        timed_data = []

        # Get the first day in the dataset, so we can use it's day of the week to anchor our other weekly data.
        first_day = self.mymidi.map_week_to_day(filtered_data[0]['Year'], filtered_data[0]['Week'])

        for r in filtered_data:
            # Convert the week to a date in that week
            week_start_date = self.mymidi.map_week_to_day(r['Year'], r['Week'], first_day.weekday())
            # To get your date into an integer format, convert that date into the number of days since Jan. 1, 1970
            days_since_epoch = self.mymidi.days_since_epoch(week_start_date)
            # Convert that integer date into a beat
            beat = self.mymidi.beat(days_since_epoch)

            timed_data.append({
                'days_since_epoch': days_since_epoch,
                'beat': beat,
                'CoalProdMillions': float(r['CoalProd']) / 1000000.0
            })

        note_list = self.make_notes(timed_data, 'CoalProdMillions')
        # Add a track with those notes
        self.mymidi.add_track(note_list)

        # Output the .mid file
        self.mymidi.save_midi()
Exemplo n.º 6
0
class Coal2Midi(object):
    ''' Adapted from Jordan Wirfs-Brock's awesome coal production sonification.
    Post here: http://insideenergy.org/2016/05/03/listen-to-u-s-coal-production-fall-off-a-cliff/
    Code and data here: https://github.com/InsideEnergy/Data-for-stories/tree/master/20160503-coal-production-sonification
    '''

    epoch = datetime(1970, 1,
                     1)  # TODO: Allow this to override the midtime epoch
    mymidi = None

    tempo = 120

    min_attack = 30
    max_attack = 255

    min_duration = 1
    max_duration = 5

    seconds_per_year = 26

    c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
    c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb']
    a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#']
    c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb']
    d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']
    c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb']

    current_key = c_major
    base_octave = 4
    octave_range = 3

    def __init__(self):
        self.csv_to_miditime()

    def read_csv(self, filepath):
        csv_file = open(filepath, 'rU')
        return csv.DictReader(csv_file, delimiter=',', quotechar='"')

    def remove_weeks(self, csv_obj):
        return [r for r in csv_obj if int(r['Week']) not in [53]]

    def round_to_quarter_beat(self, input):
        return round(input * 4) / 4

    def round_to_half_beat(self, input):
        return round(input * 2) / 2

    def make_notes(self, data_timed, data_key):
        note_list = []

        start_time = data_timed[0]['beat']

        for d in data_timed:
            note_list.append([
                # self.round_to_half_beat(d['beat'] - start_time),
                round(d['beat'] - start_time),
                self.data_to_pitch_tuned(d[data_key]),
                100,
                #mag_to_attack(d['magnitude']),  # attack
                1  # duration, in beats
            ])
        return note_list

    def data_to_pitch_tuned(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        # Another option: Linear scale, reverse order
        # scale_pct = mymidi.linear_scale_pct(0, self.maximum, datapoint, True)

        # Another option: Logarithmic scale, reverse order
        # scale_pct = mymidi.log_scale_pct(0, self.maximum, datapoint, True)

        # Pick a range of notes. This allows you to play in a key.
        mode = self.current_key

        #Find the note that matches your data point
        note = self.mymidi.scale_to_note(scale_pct, mode)

        #Translate that note to a MIDI pitch
        midi_pitch = self.mymidi.note_to_midi_pitch(note)

        return midi_pitch

    def mag_to_attack(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        #max_attack = 10

        adj_attack = (1 - scale_pct) * max_attack + 70
        #adj_attack = 100

        return adj_attack

    def csv_to_miditime(self):
        self.mymidi = MIDITime(self.tempo, 'coaltest.mid',
                               self.seconds_per_year, self.base_octave,
                               self.octave_range)
        raw_data = self.read_csv('data/coal_prod_1984_2016_weeks_summed.csv')
        filtered_data = self.remove_weeks(raw_data)

        self.minimum = self.mymidi.get_data_range(filtered_data,
                                                  'CoalProd')[0] / 1000000.0
        self.maximum = self.mymidi.get_data_range(filtered_data,
                                                  'CoalProd')[1] / 1000000.0

        timed_data = []

        # Get the first day in the dataset, so we can use it's day of the week to anchor our other weekly data.
        first_day = self.mymidi.map_week_to_day(filtered_data[0]['Year'],
                                                filtered_data[0]['Week'])

        for r in filtered_data:
            # Convert the week to a date in that week
            week_start_date = self.mymidi.map_week_to_day(
                r['Year'], r['Week'], first_day.weekday())
            # To get your date into an integer format, convert that date into the number of days since Jan. 1, 1970
            days_since_epoch = self.mymidi.days_since_epoch(week_start_date)
            # Convert that integer date into a beat
            beat = self.mymidi.beat(days_since_epoch)

            timed_data.append({
                'days_since_epoch':
                days_since_epoch,
                'beat':
                beat,
                'CoalProdMillions':
                float(r['CoalProd']) / 1000000.0
            })

        note_list = self.make_notes(timed_data, 'CoalProdMillions')
        # Add a track with those notes
        self.mymidi.add_track(note_list)

        # Output the .mid file
        self.mymidi.save_midi()
class bomb2midi(object):
    ''' Submitted by Jennifer LaFleur. '''

    epoch = datetime(
        1945, 1, 1)  # Not actually necessary, but optional to specify your own
    mymidi = None

    min_value = 0
    max_value = 5.7

    tempo = 120

    min_attack = 30
    max_attack = 255

    min_duration = 1
    max_duration = 5

    seconds_per_year = 3

    c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
    c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb']
    a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#']
    c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb']
    d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']
    c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb']

    current_key = c_major
    base_octave = 2
    octave_range = 5

    def __init__(self):
        self.csv_to_miditime()

    def read_csv(self, filepath):
        csv_file = open(filepath, 'rU')
        return csv.DictReader(csv_file, delimiter=',', quotechar='"')

    def remove_weeks(self, csv_obj):
        return [r for r in csv_obj if r['Date'] not in ['']]

    def round_to_quarter_beat(self, input):
        return round(input * 4) / 4

    def make_notes(self, data_timed, data_key):
        note_list = []

        start_time = data_timed[0]['beat']

        for d in data_timed:
            note_list.append([
                self.round_to_quarter_beat(d['beat'] - start_time),
                self.data_to_pitch_tuned(d[data_key]),
                100,
                #mag_to_attack(d['magnitude']),  # attack
                1  # duration, in beats
            ])
        return note_list

    def csv_to_miditime(self):
        raw_data = list(self.read_csv('data/bombs.csv'))
        filtered_data = self.remove_weeks(raw_data)

        self.mymidi = MIDITime(self.tempo, 'bombtest_log.mid',
                               self.seconds_per_year, self.base_octave,
                               self.octave_range, self.epoch)

        self.minimum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[0]
        self.maximum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[1]

        timed_data = []

        for r in filtered_data:
            python_date = datetime.strptime(r["Date"], "%m/%d/%Y")
            days_since_epoch = self.mymidi.days_since_epoch(python_date)
            beat = self.mymidi.beat(days_since_epoch)
            timed_data.append({
                'days_since_epoch': days_since_epoch,
                'beat': beat,
                'BombYieldMillions': float(r['Yieldnum'])
            })

        note_list = self.make_notes(timed_data, 'BombYieldMillions')
        # Add a track with those notes
        self.mymidi.add_track(note_list)

        # Output the .mid file
        self.mymidi.save_midi()

    def data_to_pitch_tuned(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        #scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        # Another option: Linear scale, reverse order
        # scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint, True)
        # print 10**self.maximum
        # Another option: Logarithmic scale, reverse order
        scale_pct = self.mymidi.log_scale_pct(0, self.maximum, datapoint, True,
                                              'log')

        # Pick a range of notes. This allows you to play in a key.
        mode = self.current_key

        #Find the note that matches your data point
        note = self.mymidi.scale_to_note(scale_pct, mode)

        #Translate that note to a MIDI pitch
        midi_pitch = self.mymidi.note_to_midi_pitch(note)
        print scale_pct, note

        return midi_pitch

    def mag_to_attack(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        #max_attack = 10

        adj_attack = (1 - scale_pct) * max_attack + 70
        #adj_attack = 100

        return adj_attack
Exemplo n.º 8
0
{'event_date': datetime (1912,7,14) , 'trips':  2  },
{'event_date': datetime (1912,7,15) , 'trips':  2  },
{'event_date': datetime (1912,7,16) , 'trips':  2  },
{'event_date': datetime (1912,7,17) , 'trips':  2  },
{'event_date': datetime (1912,7,18) , 'trips':  1  },
{'event_date': datetime (1912,7,19) , 'trips':  1  },
{'event_date': datetime (1912,7,20) , 'trips':  0  },
{'event_date': datetime (1912,7,21) , 'trips':  0  },
{'event_date': datetime (1912,7,22) , 'trips':  0  },
{'event_date': datetime (1912,7,23) , 'trips':  0  },
{'event_date': datetime (1912,7,24) , 'trips':  0  }
]

my_data_epoched = [{'days_since_epoch': mymidi.days_since_epoch(d['event_date']), 'trips': d['trips']} for d in my_data]

my_data_timed = [{'beat': mymidi.beat(d['days_since_epoch']), 'trips': d['trips']} for d in my_data_epoched]

start_time = my_data_timed[0]['beat']

def mag_to_pitch_tuned(trips):
    scale_pct = mymidi.linear_scale_pct(0, 2, trips)
    # Pick a range of notes. This allows you to play in a key.
    c_major = ['C', 'C#', 'D', 'D#', 'E', 'E#', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'B#']

    #Find the note that matches your data point
    note = mymidi.scale_to_note(scale_pct, c_major)

    #Translate that note to a MIDI pitch
    midi_pitch = mymidi.note_to_midi_pitch(note)

    return midi_pitch
Exemplo n.º 9
0
class Pebble(object):
    '''
    Lots of stuff cribbed from here: https://www.angio.net/personal/climb/speed

    '''

    g = 9.8
    mass_grams = 141  # 5 oz, or a baseball

    epoch = datetime(
        2004, 1, 1)  # Not actually necessary, but optional to specify your own
    mymidi = None

    tempo = 120

    min_velocity = 30
    max_velocity = 127

    min_impact_duration = 1
    max_impact_duration = 4

    seconds_per_year = 1

    c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
    c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb']
    a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#']
    c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb']
    d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']
    c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb']

    current_key = c_major
    base_octave = 2
    octave_range = 4

    def __init__(self):
        self.csv_to_miditime()

    def get_yearly_averages(self, rows, date_var, date_format, distance_var,
                            unit):
        years = {}
        for r in rows:
            # filter out nulls
            if r[distance_var]:
                if r[distance_var] != '':
                    # extract year
                    year = datetime.strptime(r[date_var], date_format).year
                    # make a decade
                    decade = int('%s0' % (str(year)[:-1], ))

                    # convert to meters (if feet):
                    if unit == 'feet':
                        distance_meters = self.feet_to_meters(
                            float(r[distance_var]))
                    else:
                        distance_meters = float(r[distance_var])

                    if decade not in years:
                        years[decade] = [distance_meters]
                    else:
                        years[decade].append(distance_meters)

        # now get averages
        output = []
        for year, values in years.iteritems():
            yearly_avg = {
                'year': year,
                'median_distance_meters': median(values)
            }
            output.append(yearly_avg)
            print yearly_avg

        # sort them
        return sorted(output, key=lambda k: k['year'])

    def feet_to_meters(self, feet):
        return float(feet) * 0.3048

    def time_to_impact(self, height_meters):
        return math.sqrt(2 * float(height_meters) / self.g)

    def seconds_to_beats(self, seconds):  # Just for manually setting seconds
        return seconds * (self.tempo / 60)

    def read_csv(self, filepath):
        csv_file = open(filepath, 'rU')
        return csv.DictReader(csv_file, delimiter=',', quotechar='"')

    #
    # def round_to_quarter_beat(self, input):
    #     return round(input * 4) / 4

    def velocity_on_impact(self, height_meters):  # sqrt( 2 * g * height )
        return math.sqrt(2 * self.g * float(height_meters))

    def energy_on_impact(
        self, mass, velocity
    ):  # Energy at splat time: 1/2 * mass * velocity2 = mass * g * height
        return (mass * velocity) / 2

    def energy_to_velocity(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        #scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        # Another option: Linear scale, reverse order
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum_energy,
                                                 datapoint)
        # print 10**self.maximum
        # Another option: Logarithmic scale, reverse order
        # scale_pct = self.mymidi.log_scale_pct(0, self.maximum, datapoint, True, 'log')

        velocity_range = self.max_velocity - self.min_velocity
        velocity = self.min_velocity + (scale_pct * velocity_range)
        return velocity

    def data_to_pitch_tuned(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        #scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        # Another option: Linear scale, reverse order
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum_energy,
                                                 datapoint, True)
        # print 10**self.maximum
        # Another option: Logarithmic scale, reverse order
        # scale_pct = self.mymidi.log_scale_pct(0, self.maximum, datapoint, True, 'log')

        # Pick a range of notes. This allows you to play in a key.
        mode = self.current_key

        #Find the note that matches your data point
        note = self.mymidi.scale_to_note(scale_pct, mode)

        #Translate that note to a MIDI pitch
        midi_pitch = self.mymidi.note_to_midi_pitch(note)

        return midi_pitch

    def energy_to_duration(self, datapoint):  # For impact duration, not fall
        scale_pct = self.mymidi.linear_scale_pct(self.minimum_energy,
                                                 self.maximum_energy,
                                                 datapoint)

        duration_range = self.max_impact_duration - self.min_impact_duration
        duration = self.min_impact_duration + (scale_pct * duration_range)
        return duration

    def make_falling_notes(self, data_timed, data_key, channel):
        note_list = []

        start_time = data_timed[0]['beat']

        for d in data_timed:
            note_list.append([
                [
                    d['beat'] - start_time,
                    self.mymidi.note_to_midi_pitch(
                        "C4"),  # pitch (set manually for drop)
                    100,  # velocity
                    self.seconds_to_beats(
                        d['duration_secs'])  # duration, in beats
                ],
                channel
            ])
        return note_list

    def make_splashing_notes(self, data_timed, data_key, channel):
        note_list = []

        start_time = data_timed[0]['beat']

        for d in data_timed:
            velocity = self.velocity_on_impact(d['distance_meters'])
            energy = self.energy_on_impact(self.mass_grams, velocity)
            note_list.append([
                [
                    d['beat'] - start_time + self.seconds_to_beats(
                        d[data_key]),  # falling start plus duration of fall
                    self.data_to_pitch_tuned(energy),  # pitch
                    self.energy_to_velocity(energy),  # velocity
                    self.energy_to_duration(energy)  # duration, in beats
                ],
                channel
            ])
        return note_list

    def csv_to_miditime(self):
        # raw_data = list(self.read_csv('data/groundwater_test.csv'))
        raw_data = list(self.read_csv('data/15S18E30L001M_clean.csv'))

        # yearly_data = self.get_yearly_averages(raw_data, 'Date', "%m/%d/%Y", 'wl(m)', 'meters')
        yearly_data = self.get_yearly_averages(raw_data, 'Measurement_Date',
                                               "%m-%d-%Y", 'GSWS', 'feet')

        self.mymidi = MIDITime(self.tempo, 'media_out/pebble_longterm.mid',
                               self.seconds_per_year, self.base_octave,
                               self.octave_range, self.epoch)

        self.minimum_depth = self.mymidi.get_data_range(
            yearly_data, 'median_distance_meters')[0]
        self.maximum_depth = self.mymidi.get_data_range(
            yearly_data, 'median_distance_meters')[1]

        self.minimum_energy = self.energy_on_impact(
            self.mass_grams,
            self.velocity_on_impact(
                self.mymidi.get_data_range(yearly_data,
                                           'median_distance_meters')[0]))
        self.maximum_energy = self.energy_on_impact(
            self.mass_grams,
            self.velocity_on_impact(
                self.mymidi.get_data_range(yearly_data,
                                           'median_distance_meters')[1]))

        timed_data = []

        for r in yearly_data:
            # python_date = datetime.strptime(r["Date"], "%Y-%m-%d")
            python_date = datetime.strptime('1/1/%s' % r["year"], "%m/%d/%Y")
            distance_meters = r['median_distance_meters']
            days_since_epoch = self.mymidi.days_since_epoch(python_date)
            beat = self.mymidi.beat(days_since_epoch)
            timed_data.append({
                'days_since_epoch':
                days_since_epoch,
                'beat':
                beat,
                'distance_meters':
                distance_meters,
                'duration_secs':
                self.time_to_impact(distance_meters)
            })

        falling_note_list = self.make_falling_notes(timed_data,
                                                    'duration_secs', 0)
        splashing_note_list = self.make_splashing_notes(
            timed_data, 'duration_secs', 1)

        # Add a track with those notes
        self.mymidi.add_track(falling_note_list)
        self.mymidi.add_track(splashing_note_list)

        # Output the .mid file
        self.mymidi.save_midi()
class bomb2midi(object):
    ''' Submitted by Jennifer LaFleur. '''

    epoch = datetime(1945, 1, 1)  # Not actually necessary, but optional to specify your own
    mymidi = None

    min_value = 0
    max_value = 5.7

    tempo = 120

    min_attack = 30
    max_attack = 255

    min_duration = 1
    max_duration = 5

    seconds_per_year = 3

    c_major = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
    c_minor = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb']
    a_minor = ['A', 'B', 'C', 'D', 'E', 'F', 'F#', 'G', 'G#']
    c_blues_minor = ['C', 'Eb', 'F', 'F#', 'G', 'Bb']
    d_minor = ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']
    c_gregorian = ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'A', 'Bb']

    current_key = c_major
    base_octave = 2
    octave_range = 5

    def __init__(self):
        self.csv_to_miditime()

    def read_csv(self, filepath):
        csv_file = open(filepath, 'rU')
        return csv.DictReader(csv_file, delimiter=',', quotechar='"')

    def remove_weeks(self, csv_obj):
        return [r for r in csv_obj if r['Date'] not in ['']]

    def round_to_quarter_beat(self, input):
        return round(input * 4) / 4

    def make_notes(self, data_timed, data_key):
        note_list = []

        start_time = data_timed[0]['beat']

        for d in data_timed:
            note_list.append([
                self.round_to_quarter_beat(d['beat'] - start_time),
                self.data_to_pitch_tuned(d[data_key]),
                100,
                #mag_to_attack(d['magnitude']),  # attack
                1  # duration, in beats
            ])
        return note_list

    def csv_to_miditime(self):
        raw_data = list(self.read_csv('data/bombs.csv'))
        filtered_data = self.remove_weeks(raw_data)

        self.mymidi = MIDITime(self.tempo, 'bombtest_log.mid', self.seconds_per_year, self.base_octave, self.octave_range, self.epoch)

        self.minimum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[0]
        self.maximum = self.mymidi.get_data_range(filtered_data, 'Yieldnum')[1]

        timed_data = []

        for r in filtered_data:
            python_date = datetime.strptime(r["Date"], "%m/%d/%Y")
            days_since_epoch = self.mymidi.days_since_epoch(python_date)
            beat = self.mymidi.beat(days_since_epoch)
            timed_data.append({
                'days_since_epoch': days_since_epoch,
                'beat': beat,
                'BombYieldMillions': float(r['Yieldnum'])
            })

        note_list = self.make_notes(timed_data, 'BombYieldMillions')
        # Add a track with those notes
        self.mymidi.add_track(note_list)

        # Output the .mid file
        self.mymidi.save_midi()

    def data_to_pitch_tuned(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        #scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        # Another option: Linear scale, reverse order
        # scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint, True)
        # print 10**self.maximum
        # Another option: Logarithmic scale, reverse order
        scale_pct = self.mymidi.log_scale_pct(0, self.maximum, datapoint, True, 'log')

        # Pick a range of notes. This allows you to play in a key.
        mode = self.current_key

        #Find the note that matches your data point
        note = self.mymidi.scale_to_note(scale_pct, mode)

        #Translate that note to a MIDI pitch
        midi_pitch = self.mymidi.note_to_midi_pitch(note)
        print scale_pct, note

        return midi_pitch

    def mag_to_attack(self, datapoint):
        # Where does this data point sit in the domain of your data? (I.E. the min magnitude is 3, the max in 5.6). In this case the optional 'True' means the scale is reversed, so the highest value will return the lowest percentage.
        scale_pct = self.mymidi.linear_scale_pct(0, self.maximum, datapoint)

        #max_attack = 10

        adj_attack = (1 - scale_pct) * max_attack + 70
        #adj_attack = 100

        return adj_attack
Exemplo n.º 11
0
            #in each row 'hours_since_epoch' has the time in terms of hours elapsed since epoch along with the corresponding value given in the 'out' column
            #hours since epoch is taken out using days_since_epoch() * 24
            my_out_data_epoched_hours.append({
                'hours_since_epoch':
                mymidiOUT.days_since_epoch(date_time_obj) * 24,
                'out':
                data[i]['out']
            })

            #Step 4
            #array with columns ['beat', 'in'].
            #in each row 'beat' is the time at which a particular note should occur in the song along with the corresponding 'in' value
            #calculate beat for each row using the beat() function from the corresponding hours_since_epoch values
            my_data_in_timed.append({
                'beat':
                mymidiIN.beat(my_in_data_epoched_hours[i]['hours_since_epoch'])
                * (365.25 / 24),
                'in':
                my_in_data_epoched_hours[i]['in']
            })

            #array with columns ['beat', 'out'].
            #in each row 'beat' is the time at which a particular note should occur in the song along with the corresponding 'out' value
            #calculate beat for each row using the beat() function from the corresponding hours_since_epoch values
            my_data_out_timed.append({
                'beat':
                mymidiOUT.beat(
                    my_out_data_epoched_hours[i]['hours_since_epoch']) *
                (365.25 / 24),
                'out':
                my_out_data_epoched_hours[i]['out']