示例#1
0
    def record_midi_wav(mid_):
        # write mid_ to file
        with open("test.mid", "wb") as bin_file:
            mid_.writeFile(bin_file)

        s = Server().boot().start()

        # create app synth
        midi_reader = Notein()
        amp = MidiAdsr(midi_reader['velocity'])
        pit = MToF(midi_reader['pitch'])
        osc = SineLoop(freq=pit, feedback=0, mul=amp).mix(1)
        rev = STRev(osc, revtime=1, cutoff=4000, bal=0.2).out()

        # create recorder
        rec = Record(rev, buffering=2, filename='beat.wav', quality=0.4)
        clean = Clean_objects(12, rec)
        clean.start()

        midi_reader = MidiFile('test.mid')

        # makeshift infinite loop
        for message in midi_reader.play():
            s.addMidiEvent(*message.bytes())

        s.stop()
示例#2
0
    #useful for debugging
    show = False
    if "-v" in argv:
        show = True

    #Pyo server/objects
    s = Server().boot()
    s.start()
    wav = SineLoop(freq=2 * Pi * 261.626)
    notes = dict()
    notes['a'] = 220
    notes['b'] = 246.942
    notes['c'] = 261.626
    notes['d'] = 293.665
    notes['e'] = 329.628
    notes['f'] = 349.228
    notes['g'] = 391.995
    notes['highA'] = 440

    try:
        main()
    except KeyboardInterrupt:
        pass
    wav.stop()
    #otherOut.stop()
    s.stop()
    cls()
    print "Stopped theremin"
    exit()
class MusebotBase(object):
  '''
  This class includes the functionality required by all Musebots, namely the
  ability to parse the config file, communicate with the server, and gracefully
  start up and shut down as per the Musebot communication spec.
  '''
  class Heartbeat:
    def __init__(self, config={}):
      self._del = 1 # 1 beat per second
      self._msg = [config['id']]
      self._osc = OscDataSend('s', config['mc_listen_port'],
        '/agent/alive', host=config['mc_hostname'])

    def beat(self):
      while True:
        self._osc.send(self._msg)
        sleep(self._del)
        if not serverBooted(): break

    def start(self, run_as_deamon=True):
      self._thread = Thread(target=self.beat)
      self._thread.daemon = run_as_deamon # True => die when main thread dies
      self._thread.start()

  def __init__(self, config_path='config.txt'):
    self.parse_config_file(config_path)
    # init members & properties
    self._server = Server().boot() # do first
    self._heartbeat = MusebotBase.Heartbeat(self._config)
    self._osc_listeners = {}
    self._osc_recv = OscDataReceive(self.port, '/', self.osc_listener_callback)
    # register osc listeners
    self.register_osc_listener('/agent/gain', self.gain)
    self.register_osc_listener('/agent/kill', self.shutdown)
    self.register_osc_listener('/agent/quit', self.shutdown)
    self.register_osc_listener('/agent/off',  self.shutdown)

  def parse_config_file(self, config):
    with open(config) as f:
      self._config = {}
      for line in f:
        k,v = line.split()
        if k in {'mc_listen_port', 'my_listen_port', 'output_channels'}:
          self._config[k] = int(v)
        else:
          self._config[k] = v

  def run(self):
    '''Implemented in user code'''
    pass

  def start(self):
    self._heartbeat.start()
    self.run()

  def register_osc_listener(self, address, func):
    self._osc_listeners[address] = func
    self._osc_recv.addAddress(address)

  def osc_listener_callback(self, address, *args):
    if address in self._osc_listeners:
      self._osc_listeners[address](args)

  ############################################################################
  # osc callbacks
  #

  def shutdown(self, *args):
    print(self.id+' shutting down!')
    self._server.stop()
    self._server.closeGui()

  def gain(self, gain, *args):
    self._server.amp = float(gain[0])

  ############################################################################
  # properties
  #

  @property
  def server(self):
    return self._server

  @property
  def config(self):
    return deepcopy(self._config)

  @property
  def id(self):
    return self.config['id']

  @property
  def port(self):
    return self.config['my_listen_port']

  @property
  def hostname(self):
    return self.config['mc_hostname']

  @property
  def hostport(self):
    return self.config['mc_listen_port']

  @property
  def heartbeat(self):
    return self._heartbeat
示例#4
0
class MidiCube:
    def __init__(self, pers_mgr=PersistenceManager()):
        self.inputs = {}
        self.outputs = {}
        self.reg_mgr = RegistrationManager()
        self.pers_mgr = pers_mgr

    def reg(self):
        return self.reg_mgr.cur_reg

    def add_input(self, device: MidiInputDevice):
        device.cube = self
        self.inputs[device.get_identifier()] = device

        #Add Binding callback
        def callback(msg: mido.Message):
            for binding in self.reg().bindings:
                binding.apply(msg.copy(), self, device)

        device.add_listener(MidiListener(-1, callback))

    def add_output(self, device: MidiOutputDevice):
        device.cube = self
        self.outputs[device.get_identifier()] = device
        print('Added output: ' + device.get_identifier())

    def load_devices(self):
        for name in mido.get_input_names():
            device = mido.open_input(name)
            self.add_input(PortInputDevice(device))
        for name in mido.get_output_names():
            device = mido.open_output(name)
            self.add_output(PortOutputDevice(device))

    def init(self):
        #Boot server
        self.server = Server(audio='jack')
        self.server.deactivateMidi()
        self.server.boot().start()
        #Init devices
        for device in self.outputs.values():
            device.init()
        #Load Registrations
        self.pers_mgr.load(self)
        print("Loaded Registrations")

        def cb(r):
            for o in self.outputs.values():
                o.on_reg_change()

        self.reg_mgr.add_listener(cb)
        #Init devices
        for device in self.outputs.values():
            device.on_reg_change()

    def close(self, save=True):
        for key, inport in self.inputs.items():
            try:
                inport.close()
            except:
                pass
        for key, outport in self.outputs.items():
            try:
                outport.close()
            except:
                pass
        if save:
            self.pers_mgr.save(self)
            print("Saved registrations!")
        self.server.stop()

    def create_menu(self):
        #Option list
        options = [
            midicube.menu.SimpleMenuOption(self.__bind_device_menu,
                                           "Bind Devices", ""),
            midicube.menu.SimpleMenuOption(self.__setup_device_menu,
                                           "Set Up Devices", ""),
            midicube.menu.SimpleMenuOption(self.__delete_binding_menu,
                                           "Delete Bindings", ""),
            midicube.menu.SimpleMenuOption(self.__registration_menu,
                                           "Registrations", "")
        ]
        menu = midicube.menu.OptionMenu(options, history=True)
        return menu

    def __bind_device_menu(self):
        #Callback
        def enter():
            self.reg().bindings.append(
                DeviceBinding(in_device.curr_value(), out_device.curr_value(),
                              in_channel.curr_value(),
                              out_channel.curr_value()))
            #out_device.curr_value().bind(in_device.curr_value(), in_channel.curr_value(), out_channel.curr_value())
            return None

        #Options
        in_device = midicube.menu.ValueMenuOption(enter, "Input Device",
                                                  [*self.inputs.keys()])
        out_device = midicube.menu.ValueMenuOption(enter, "Output Device",
                                                   [*self.outputs.keys()])
        in_channel = midicube.menu.ValueMenuOption(enter, "Input Channel",
                                                   range(-1, 16))
        out_channel = midicube.menu.ValueMenuOption(enter, "Output Channel",
                                                    range(-1, 16))
        #Menu
        return midicube.menu.OptionMenu(
            [in_device, out_device, in_channel, out_channel])

    def __setup_device_menu(self):
        #Callback
        def enter():
            return device.curr_value().create_menu()

        #Options
        device = midicube.menu.ValueMenuOption(enter, "Device",
                                               [*self.outputs.values()])
        #Menu
        return midicube.menu.OptionMenu([device])

    def __delete_binding_menu(self):
        #Callback
        def enter():
            if binding.curr_value() != None:
                self.reg().bindings.remove(binding.curr_value())
            return None

        #Options
        binding = midicube.menu.ValueMenuOption(enter, "Delete Bindings",
                                                self.reg().bindings)
        #Menu
        return midicube.menu.OptionMenu([binding])

    def __registration_menu(self):
        #TODO Refresh menu when registrations are changed
        #Callbacks
        def select_reg():
            self.reg_mgr.select(registration.curr_value())
            return None

        def save_reg_menu():
            reg = self.reg()

            def save_reg(name):
                reg.name = name
                self.reg_mgr.add_registration(reg)
                return None

            return midicube.menu.InputMenu(save_reg, "Save as", reg.name)

        def overwrite_reg_menu():
            reg = self.reg()

            def overwrite_name(name):
                def overwrite_reg(new_name):
                    del self.reg_mgr.registrations[name]
                    reg.name = new_name
                    self.reg_mgr.add_registration(reg)

                return midicube.menu.InputMenu(overwrite_reg, "New Name",
                                               reg.name)

            return midicube.menu.InputMenu(overwrite_name, "Overwrite",
                                           reg.name)

        def delete_reg():
            del self.reg_mgr.registrations[self.reg().name]
            return None

        #Options
        registration = midicube.menu.ValueMenuOption(
            select_reg, "Select Registration",
            [*self.reg_mgr.registrations.values()])
        save = midicube.menu.SimpleMenuOption(save_reg_menu,
                                              "Save Registration", "")
        overwrite = midicube.menu.SimpleMenuOption(overwrite_reg_menu,
                                                   "Overwrite Registration",
                                                   "")
        delete = midicube.menu.SimpleMenuOption(delete_reg,
                                                "Delete Registration", "")
        #Menu
        return midicube.menu.OptionMenu(
            [registration, save, overwrite, delete])
示例#5
0
run = True

server = Server().boot()
server.start()

met = Metro(.125, 12).play()

players.append(Player(met, notes1))
players.append(Player(met, notes2))
players.append(Player(met, notes3))

while run:
    for event in pygame.event.get():
        if event.type == pygame.KEYUP:
            for player in players:
                player.note_off(chr(event.key))

            if event.key == ESC:
                run = False
                break
            if event.key == PLUS:
                met.time = min(.5, met.time + .01)
            if event.key == MINUS:
                met.time = max(.07, met.time - .01)

        if event.type == pygame.KEYDOWN:
            for player in players:
                player.note_on(chr(event.key))

server.stop()
示例#6
0
class MusicPlayer:
    """Playback engine for sequencer samples and sounds"""

    NUM_PAGES = 8
    NUM_ROWS = 8
    NUM_COLS = 8
    NUM_TRACKS = 3
    NUM_BEATS = NUM_PAGES * NUM_COLS

    SECONDS_PER_MIN = 60.0

    # Parameters for GUI to build sliders
    MIN_TEMPO = 40.0
    MAX_TEMPO = 240.0
    MIN_VOLUME = 0.0
    MAX_VOLUME = 1.0
    MIN_REVERB = 0.0
    MAX_REVERB = 1.0 

    # Instrument descriptive constants
    WAVETABLE_A = 0
    WAVETABLE_B = 1
    DRUM_KIT = 2

    def __init__(self):
        """Constructor for music_player"""
        """Make sure to call add_gui once initialized"""
        self.instruments = [] #instrument/track volume is here
        self.tempo = 120.0 #BPM (for now)
        self.global_volume = 0.75 #between 0 and 1
        self.page_index = 0 #1st page
        self.play_all = False
        self.playhead_index = 0
        self.beat_index = 0

        self.server = Server(duplex=0)
        """Set proper output device for latency-free playback on Windows"""
        """Source: https://groups.google.com/d/msg/pyo-discuss/9fvFiGbch3c/tzJTfbpLUY8J"""
        if platform.system() == "Windows":
            out_devices = pa_get_output_devices()
            od_index = 0
            for od in out_devices[0]:
                if "Primary Sound Driver" in od:
                    pai = int(out_devices[1][od_index])
                    self.server.setOutputDevice(pai)
                    break
                od_index += 1

        self.server.boot()
        self.server.start()

        metronome_time = self.SECONDS_PER_MIN / self.tempo
        self.metronome = Metro(time=metronome_time)
        self.metronome_callback = TrigFunc(self.metronome, function=self.step)
        
        # Create instruments
        wavetable_a = WaveInstrument(self, WaveInstrument.BASS)
        wavetable_b = WaveInstrument(self, WaveInstrument.LEAD)
        drums = DrumInstrument(self)
        
        self.instruments.append(wavetable_a)
        self.instruments.append(wavetable_b)
        self.instruments.append(drums)

        self.mixer_setup()
    
    def mixer_setup(self):
        # Combine all tracks in mixer
        self.track_mixer = Mixer(outs=1)
        for inst_index in range(0, len(self.instruments)):
            instrument = self.instruments[inst_index]
            generator = instrument.get_generator()
            self.track_mixer.addInput(inst_index, generator)
            self.track_mixer.setAmp(inst_index, 0, instrument.get_volume())
        
        # Prepare master output
        self.master_out = Mixer(outs=1, chnls=2)
        self.master_out.addInput(0, self.track_mixer[0])
        self.master_out.setAmp(0, 0, self.global_volume)
        self.master_out.out()

    def add_gui(self, gui):
        """ Sets the GUI that this music player must instruct to update playhead.
        Must be called right after constructor before operation.

        Arguments:
        gui: GUI object monitoring this player

        """
        self.gui = gui
    
    def terminate(self):
        """Terminate MusicPlayer server in preparation for shutdown"""
        self.server.stop()
        self.server.shutdown()

    def step(self):
        """ Step the music player through next beat """
        # Set GUI to reflect current beat
        self.gui.update_playhead()
        
        # Play step for instruments
        for instrument in self.instruments:
            instrument.play_step()

        # For next iteration, increment playhead and beat indices
        self.playhead_index = (self.playhead_index + 1) % self.NUM_COLS
        if (self.play_all == True):
            self.beat_index = (self.beat_index + 1) % self.NUM_BEATS
        elif (self.play_all == False):
            self.beat_index = (self.page_index * self.NUM_COLS) +\
                              self.playhead_index

    def add_network_handler(self, network_handler):
        self.network_handler = network_handler
        
    """playback methods"""
    def play(self):
        self.metronome.play()

    def pause(self):
        for instrument in self.instruments:
            instrument.pause()
        self.metronome.stop()

    def set_session(self, session):
        """used to load a session into the music player"""
        # Reload pertinent MusicPlayer variables
        self.set_tempo(session.tempo)

        # Reconstruct each instrument from session data
        self.instruments = []
        instrument_data = session.instrument_data
        for data in instrument_data:
            volume = data.volume
            reverb_mix = data.reverb_mix
            notes = data.notes
            if isinstance(data, WaveInstrumentData):
                wavetype = data.wavetype
                wave_instrument = WaveInstrument(self, wavetype, volume, 
                                                 reverb_mix, notes)
                self.instruments.append(wave_instrument)
            elif isinstance(data, DrumInstrumentData):
                drum_instrument = DrumInstrument(self, volume, reverb_mix,
                                                 notes)
                self.instruments.append(drum_instrument)

        # Reload mixer to reflect new instruments
        self.mixer_setup()

    """ Modifiers """
    def set_note(self, note):
        instrument = self.instruments[note.track_id]
        instrument.set_note(note)

    def set_global_volume(self, volume):
        self.global_volume = volume
        self.master_out.setAmp(0, 0, volume)

    def set_volume(self, track_id, volume):
        self.instruments[track_id].set_volume(volume)
        self.track_mixer.setAmp(track_id, 0, volume)
    
    def set_reverb(self, track_id, reverb):
        self.instruments[track_id].set_reverb(reverb)

    def set_tempo(self, new_tempo):
        new_time = self.SECONDS_PER_MIN / new_tempo
        self.metronome.setTime(new_time)
        self.tempo = new_tempo

    """getter methods"""
    def get_session(self):
        """Get descriptive MusicPlayer session to restore later"""
        session = Session(self, self.instruments)
        return session

    """getter methods for GUI"""
    def get_names(self, track_id):
        return self.instruments[track_id].get_names()

    def get_reverb(self, track_id):
        return self.instruments[track_id].get_reverb()

    def get_volume(self, track_id):
        return self.instruments[track_id].get_volume()

    def get_global_volume(self):
        return self.global_volume

    def get_tempo(self):
        return self.tempo

    def get_note(self, track_id, page_index, position, pitch):
        pass

    def get_current_page(self, track_id):
        instrument = self.instruments[track_id]
        notes = instrument.get_page(self.page_index)
        return notes