def test_saw():
    
    synth = Synth(44100)
    
    synth.setParameter(SynthParameters.OSC_1_WAVEFORM, Waveform.SAW)
    synth.setParameter(SynthParameters.OSC_2_WAVEFORM, Waveform.SAW)
    synth.setParameter(SynthParameters.OSC_3_WAVEFORM, Waveform.SAW)

    synth.noteOn(10)

    out = []
        
    for i in range(44100):
        out.append(synth.getSample())
        
    synth.noteOff(10)
def test_whiteNoise():
    
    synth = Synth(44100)
    
    synth.setParameter(SynthParameters.OSC_1_WAVEFORM, Waveform.WHITE_NOISE)
    synth.setParameter(SynthParameters.OSC_2_WAVEFORM, Waveform.WHITE_NOISE)
    synth.setParameter(SynthParameters.OSC_3_WAVEFORM, Waveform.WHITE_NOISE)

    synth.noteOn(60)

    out = []
        
    for i in range(44100):
        out.append(synth.getSample())
        
    synth.noteOff(60)
Exemple #3
0
def play_and_analyze(parameters, instrument_name, gesture, plot):

    duration = len(parameters)/GESTURE_SAMPLING_FREQUENCY
    my_synth = Synth(duration, instrument_name, None, GESTURE_SAMPLING_FREQUENCY)

    output_analysis = []

    for step_parameters in parameters:
        my_synth.set_synthesis_parms(step_parameters)
        errcode = my_synth.step_synth()
        output_analysis.append(my_synth.get_analysis_values())

    output_analysis = np.stack(output_analysis)
    my_synth.cleanup()

    if plot:
        x = np.arange(len(parameters))

        gesture_plot_height = int(np.ceil(gesture.shape[1]/2))
        total_plot_height = int(gesture_plot_height + 4)

        # Find the most similar
        simils = []
        for g_axis in gesture.T:
            simils.append([ mse(g_axis, feature) for feature in output_analysis.T ])

        most_simil = [ np.argmin(s) for s in simils ]

        # Plot gesture
        iv, jv = np.meshgrid(np.arange(gesture_plot_height), np.arange(2), indexing='ij')
        plot_coords = list(zip(np.ndarray.flatten(iv), np.ndarray.flatten(jv)))

        plot_shape = (total_plot_height, 2)

        for k, g_axis in enumerate(gesture.T):
            ax = plt.subplot2grid(plot_shape, plot_coords[k])
            ax.plot(x, g_axis, label='gesture axis {}'.format(k), color=colors[k])
            ax.legend(loc='upper right')
            ax.set_ylim(0,1)

        # Plot audio features
        iv, jv = np.meshgrid(np.arange(gesture_plot_height, total_plot_height),
                             np.arange(2), indexing='ij')
        plot_coords = list(zip(np.ndarray.flatten(iv), np.ndarray.flatten(jv)))

        for k, feature in enumerate(output_analysis.T):
            color = 'b'
            if k in most_simil:
                if most_simil.count(k) > 1:
                    color = 'k'
                else:
                    color = colors[most_simil.index(k)]

            audio_features = ['amp', 'env_crest', 'pitch', 'centroid',
                              'flatness', 's_crest', 'flux', 'mfcc_diff']

            ax = plt.subplot2grid(plot_shape, plot_coords[k])
            ax.plot(x, feature, color=color, label=audio_features[k])
            ax.legend(loc='upper right')
            ax.set_ylim(0,1)


        similarity = np.sum([ min(s) for s in simils ])
        plt.savefig('/shape/sounds/{}.png'.format(my_synth.filename), dpi=300)
        plt.close()

    return (my_synth.filename, similarity)
    def getSynth(self,
                               samplerate,
                               melodyToPad      = 0.5,
                               calmToExciting   = 0.5,
                               brightToDark     = 0.5,
                               softToHard       = 0.5,
                               clearToRich      = 0.5,
                               ):
        """This method returns a Synth matching the requirements.
        
        It uses REALLY COOL algorithms to embed the parameters into the Synth.
        Python's random module is used to generate random parameters. Therefore, a seed can be used to 
        generate the exact same song twice. That seed needs to be fed to the Composer instance.
        
        The beta-distribution is used a lot in this code as its density function can be centered 
        very easily and it naturally yields values in [0.0, 1.0].
        
        More on the beta distribution in the misc.additionalmath module.
        """

        """Set up synth."""
        synth = Synth(samplerate)
        
        """Waveforms"""
        synth.setParameter(SynthParameters.OSC_ALL_WAVEFORM, Waveform.SAW)
        
        """Oscillator gain"""
        #synth.setParameter(SynthParameters.OSC_ALL_GAIN, 1.0)
        synth.setParameter(SynthParameters.OSC_1_GAIN, 1.0)
        synth.setParameter(SynthParameters.OSC_2_GAIN, 1.0)
        synth.setParameter(SynthParameters.OSC_3_GAIN, 1.0)
        
        """Oscillator detune
        
        Depends on 
            - brightToDark
            - clearToRich
        """
        for i in range(SynthParameters.NUM_OSCILLATORS):
            mode = (brightToDark + 2.0 * clearToRich) / 3.0
            steepness = 1000      # high steepness, we dont want to much detune
            maxDetune = 50.0    # 50 cents
            detune = 2.0 * maxDetune * beta(mode, steepness) - maxDetune
            synth.setParameter(SynthParameters.OSC_1_DETUNE + i, detune)

        
        """Volume envelope
        
        Depends on:
            - melodyToPad
            - calmToExciting
            - softToHard
        """
        maxAttack   =  4.0
        maxDecay    =  3.0
        maxRelease  =  10.0
        
        for i in range(SynthParameters.NUM_OSCILLATORS):
            mode = (5.0 * melodyToPad + (1.0 - calmToExciting) + (1.0 - softToHard)) / 7.0
            steepness = 40
            attack  = maxAttack     * beta(mode, steepness) ** 1.5
            decay   = maxDecay      * beta(mode, steepness) ** 1.5
            
            mode = (3.0 * melodyToPad + (1.0 - calmToExciting) + (1.0 - softToHard)) / 5.0
            steepness = 40
            release = maxRelease    * beta(mode, steepness)

            synth.setParameter(SynthParameters.OSC_1_VOLUME_ENEVELOPE_ATTACK + i, attack)
            synth.setParameter(SynthParameters.OSC_1_VOLUME_ENEVELOPE_DECAY + i, decay)
            synth.setParameter(SynthParameters.OSC_1_VOLUME_ENEVELOPE_RELEASE + i, release)
        
        """Cutoff + Resonance
        
        Depend on:
            - melodyToPad        (resonance not)
            - calmToExciting
            - softToHard
        """ 
        # for i in range(SynthParameters.NUM_OSCILLATORS):
        # cutoff
        mode = ((1.0 - melodyToPad) + calmToExciting + 3.0 * softToHard) / 5.0
        steepness = 20
        cutoff = beta(mode, steepness) ** 3.0
        
        # resonance
        mode = (calmToExciting + softToHard) / 2.0
        steepness = 2
        resonance = beta(mode, steepness) ** 1.5
        
        synth.setParameter(SynthParameters.OSC_ALL_CUTOFF, cutoff)
        synth.setParameter(SynthParameters.OSC_ALL_RESONANCE, resonance)
        
        
        """LFO
        
        Depend on 
            - calmToExciting
            - softToHard
        """
        mode = calmToExciting
        steepness = 3
        frequency = beta(mode, steepness) ** 2.0
        
        mode = (calmToExciting + softToHard) / 2.0
        steepness = 20
        lfoToVolume = beta(mode, steepness) ** 6.0
        
        mode = (calmToExciting + softToHard) / 2.0
        steepness = 20
        lfoToFilter = beta(mode, steepness) ** 6.0
        
        synth.setParameter(SynthParameters.LFO_FREQUENCY, frequency)
        synth.setParameter(SynthParameters.LFO_TO_VOLUME, lfoToVolume)
        synth.setParameter(SynthParameters.LFO_TO_FILTER, lfoToFilter)

        return synth