#Pari&Dispari
Explore tagged Tumblr posts
marcogiovenale · 2 years ago
Text
corrado costa: "libro che insegna a parlare"
corrado costa: “libro che insegna a parlare”
Da un libro di Coco Gordon pubblicato da Pari&Dispari, di Rosanna Chiessi  
youtube
View On WordPress
1 note · View note
mbuoninfante · 6 years ago
Text
MonoSynth in ChucK - pt.8
Parte 8
SCOPO
Implementazione dei 4 oscillatori classici (limitati in banda):
sine
square
triangle
sawtooth
Utilizzo di array di UGen e perfezionamento dell'algoritmo di gestione degli oscillatori.
PREREQUISITI
Per poter utilizzare questo programma serve avere un controller MIDI connesso al computer, o una virtual MIDI keyboard. Questo va connesso (o aperto nel caso di una tastiera virtuale), prima di far partire il programma.
Conoscenza base del protocollo MIDI (https://it.wikipedia.org/wiki/Musical_Instrument_Digital_Interface - http://www.nyu.edu/classes/bello/FMT_files/8_MIDIcomms.pdf - https://www.nyu.edu/classes/bello/FMT_files/9_MIDI_code.pdf)
Conoscenza base della sintesi additiva e della serie di Fourier
ANALISI DEL PROGRAMMA
Questo programma non differisce troppo da quello presentato nel precedente tutorial.
All’oscillatore a forma d’onda quadra sono stati affiancati quelli: sinusoidale, triangolare e a dente di sega.
Il programma inizia nel seguente modo:
// RTcMix Lookup table: https://en.wikipedia.org/wiki/Real-time_Cmix Gen10 oscils[13]; Phasor phasor;              // utilizzato per controllare le look-up table contentute in 'oscils' 0 => int selected_oscil;    // oscillatore selezionato (0. sine, 1. square, 2. tri, 3. sawtooth) -1 => int previous_oscil;   // variabile utilizzata nel ciclo while ["SINE", "SQUARE", "TRIANGLE", "SAWTOOTH"] @=> string waveform_name[];
Nella prima riga di codice si e’ utilizzato un array di UGen, contenente 13 Gen10 utilizzati come lookup table.
Come si vedra’ di seguito nel codice, l’array e’ suddiviso nel seguente modo:
oscils[0] = oscillatore sinusoidale
da oscils[1] a oscils[4] = oscillatore onda quadra (I 4 oscillatori hanno differente contenuto armonico, come nel case del tutorial precedente)
da oscils[5] a oscils[8] = oscillatore onda triangolare
da oscils[9] a oscils[12] = oscillatore onda a dente di sega
Di seguito la variabile selected_oscil viene dichiarata. Questa rappresenta l’oscillatore selezionato (sine, square, triangle, sawtooth). La variabile previous_oscil invece, rappresenta l’ultimo oscillatore selezionato e viene’ utilizzata nel ciclo while.
Un array di tipo string contenente I nomi dei vari oscillatori viene dichiarato. Questo e’ utilizzato per stampare sulla console il nome dell’oscillatore selezionato.
Il codice che segue, fini al punto in cui il ciclo while viene definito, e’ praticamente identico a quello del tutorial precedente.
Qui si ha:
// loop infinito while( true ) {    // avanza ad ogni messaggio MIDI ricevuto    m_in => now;    while( m_in.recv( msg_in ) )    {        if( msg_in.data1 == ( NOTE_ON + MIDI_CHANNEL ) && msg_in.data3 != 0 )        {            // resetta il volume prima di generare una nuova nota per evitare 'glitch'            env.duration( 3::ms );            env.keyOff(1);            3::ms => now;            msg_in.data2 => midi_note;            set_oscils( midi_note );        // seleziona la wavetable in base alla nota ricevuta e l’oscillatore selezionato            Std.mtof( midi_note ) => fr;    // conversione da MIDI a Freq in Hz            line.target( fr );              // assegnare la frequenza a 'line' che controlla la freq dell'oscillatore            msg_in.data2 => last_note;            msg_in.data3 * divided_by_127 => float amplitude;            env.gain( amplitude );            env.duration( attack_time );            env.keyOn(1);        }        // controlla che il messaggio MIDI sia un NOTE OFF o un NOTE ON con velocity 0        // in entrambi i casi la nota MIDI deve combaciare con l'ultima suonata (playedNote)        else if( ( msg_in.data1 == ( NOTE_ON + MIDI_CHANNEL ) && msg_in.data3 == 0 && msg_in.data2 == last_note )                  || ( msg_in.data1 == ( NOTE_OFF + MIDI_CHANNEL ) && msg_in.data2 == last_note ) )        {            env.duration( release_time );            env.keyOff(1);        }        // portamento        else if( msg_in.data1 == ( CTRL_CHANGE+MIDI_CHANNEL ) && msg_in.data2 == knobs[0] )        {            set_interp( msg_in.data3 ) => freq_interpolation;            line.time( freq_interpolation );        }        // seleziona la forma d'onda        else if( msg_in.data1 == ( CTRL_CHANGE+MIDI_CHANNEL ) && msg_in.data2 == knobs[1] )        {            msg_in.data3 * 4 => int x;            x / 128 => selected_oscil; if( selected_oscil != previous_oscil )            {                set_oscils( midi_note );        // seleziona la wavetable in base alla nota ricevuta e l'oscillatore selezionato                <<< "waveform: " + waveform_name[ selected_oscil ] >>>;                selected_oscil => previous_oscil;            }        }    } }
L’ultimo else if presente nel ciclo while e’ l’unica aggiunta al codice del tutorial 7.
Viene utilizzato il secondo knob del controller (Novation Launchkey nel caso specifico) per selezionare il tipo di oscillatore. Ogni qual volta select_oscil cambia valore, l’oscillatore selezionato cambia e viene stampato sulla console il suo nome.
La sezione FUNZIONI contiente set_interp, gia’ discussa nel tutorial precedente, e altri due funzioni: set_oscils e init_oscils.
Quest’ultima viene utilizzata per inizializzare I Gen10 con le diverse forme d’onda:
function void init_oscils() {    /*        Inizializza l'array di Gen10 'oscils'.        Il primo elemento dell'array e' una sinusoide, a seguire si ha        onda quadra, triangolare e dente di sega, le quali utilizzano        4 Gen10 ognuna.    */    float coefficients[0];            // coefficienti degli UGen Gen10    // onda sinusoidale - oscils[0]    coefficients.size(1);    1 => coefficients[0];    oscils[0].coefs( coefficients );    // onda quadra - formula: y = sum[(1/k)*sin(2PI*f*k*t)]; con k=1,3,5,7,9,...    // quadra: 14 parziali - oscils[1]    for( 1 => int c; c < 15; c++ )    {        ( ( c * 2 ) - 1 ) => int odd; // solo numeri dispari        coefficients.size( odd );     // ridimensiona l'array        1. / odd => float amp;        // 1/n        amp => coefficients[ odd-1 ];    }    oscils[1].coefs( coefficients );    // quadra: 7 parziali - oscils[2]    for( 1 => int c; c < 8; c++ )    {        ( ( c * 2 ) - 1 ) => int odd;        coefficients.size( odd );        1. / odd => float amp;        amp => coefficients[ odd-1 ];    }    oscils[2].coefs( coefficients );    // quadra: 3 parziali - oscils[3]    for( 1 => int c; c < 4; c++ )    {        ( ( c * 2 ) - 1 ) => int odd;        coefficients.size( odd );        1. / odd => float amp;        amp => coefficients[ odd-1 ];    }    oscils[3].coefs( coefficients );    // quadra: 1 parziale - sinusoide - oscils[4]    for( 1 => int c; c < 2; c++ )    {        ( ( c * 2 ) - 1 ) => int odd;        coefficients.size( odd );        1. / odd => float amp;        amp => coefficients[ odd-1 ];    }    oscils[4].coefs( coefficients );    // onda triangolare - formula: y = sum[(1/k^2)*sin(2PI*f*k*t + theta)]; con k=1,3,5,7,9,... e theta=0,180,0,180 in gradi    // triangolare: 14 parziali - oscils[5]    for( 1 => int c; c < 15; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[5].coefs( coefficients );    // triangolare: 7 parziali - oscils[6]    for( 1 => int c; c < 8; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[6].coefs( coefficients );    // triangolare: 3 parziali - oscils[7]    for( 1 => int c; c < 4; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[7].coefs( coefficients );    // triangolare: 1 parziale - sinusoide - oscils[8]    for( 1 => int c; c < 2; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[8].coefs( coefficients );    // onda a dente di sega - formula: y = sum[(1/k)*sin(2PI*f*k*t)]; con k=1,2,3,4,5,...    // dente di sega: 14 parziali - oscils[9]    for( 1 => int c; c < 15; c++ )    {        coefficients.size( c );       // ridimensiona l'array        ( 1. / c ) => float amp;      // 1/n        amp => coefficients[ c-1 ];    }    oscils[9].coefs( coefficients );    // dente di sega: 7 parziali - oscils[10]    for( 1 => int c; c < 8; c++ )    {        coefficients.size( c );       // ridimensiona l'array        ( 1. / c ) => float amp;      // 1/n        amp => coefficients[ c-1 ];    }    oscils[10].coefs( coefficients );    // dente di sega: 3 parziali - oscils[11]    for( 1 => int c; c < 4; c++ )    {        coefficients.size( c );      // ridimensiona l'array        ( 1. / c ) => float amp;     // 1/n        amp => coefficients[ c-1 ];    }    oscils[11].coefs( coefficients );    // dente di sega: 1 parziale - sinusoide - oscils[12]    for( 1 => int c; c < 2; c++ )    {        coefficients.size( c );      // ridimensiona l'array        ( 1. / c ) => float amp;     // 1/n        amp => coefficients[ c-1 ];    }    oscils[12].coefs( coefficients ); }
Mentre set_oscils seleziona il corretto Gen10 in base alla nota suonata e l’oscillatore selezionato.
Come nel tutorial 7, piu’ la nota suonata e’ alta, meno armoniche sono necessarie.
function void set_oscils( int x ) {    /*        Seleziona l'UGen Gen10 in base alla nota ricevuta.        I diversi Gen10 hanno un diverso numero di armoniche,        piu' e' alta la nota selezionata meno armoniche si avranno        per evitare problemi di aliasing    */    0 => int pointer;     // utilizzato come puntatore per l'array 'oscils'    // quando l'oscillatore selezionato NON e' sinusoidale    if( selected_oscil > 0 )    {        ( ( selected_oscil - 1 ) * 4 ) + 1 => pointer;        if( x <= 70 && oscils[ pointer ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == pointer )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }        else if(  x > 70 && x <= 90 && oscils[ pointer + 1 ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == ( pointer + 1 ) )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }        else if( x > 90 && x <= 108 && oscils[ pointer + 2 ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == ( pointer + 2 ) )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }        else if( x > 108 && x <= 127 && oscils[ pointer + 3 ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == ( pointer + 3 ) )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }    }    // quando l'oscillatore selezionato e' sinusoidale    else if( selected_oscil == 0 )    {        if( oscils[ pointer ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == pointer )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }    } }
Nonostante il numero di righe contenute in questa funzione possa sembrare elevato, set_oscil non contiene nessun costrutto particolare ed il codice al suo interno e’ abbastanza semplice.
Per prima cosa si controlla se l’oscillatore selezionato e’ quello sinusoidale ed in tal caso viene connesso il primo Gen10 contenuto in oscils[] (oscils[0]).
In caso l’oscillatore selezionato non e’ quello sinusoidale, viene considerato il pitch della nota suonata e viene selezionato il giusto oscillatore con il giusto contenuto armonico (piu’ alta e’ la nota, meno armoniche sono necessarie).
A seguire il programma intero:
/*-----------------------INFO------------------------- PREMI "Add Shred" per lanciare il programma e "Remove Shred" per term_inarlo. "Replace Shred" serve a far ripartire il programma. ----------------------------------------------------*/ // RTcMix Lookup table: https://en.wikipedia.org/wiki/Real-time_Cmix Gen10 oscils[13]; Phasor phasor;              // utilizzato per controllare le look-up table contentute in 'oscils' 0 => int selected_oscil;    // oscillatore selezionato (0. sine, 1. square, 2. tri, 3. sawtooth) -1 => int previous_oscil;   // variabile utilizzata nel ciclo while ["SINE", "SQUARE", "TRIANGLE", "SAWTOOTH"] @=> string waveform_name[]; Step step => Envelope line => phasor; Envelope env => Gain master => dac; step.next(1);               // imposta il valore di 'step' su 1 phasor.sync(0); init_oscils();              // inizializza gli UGen Gen10 // connessioni MIDI MidiIn m_in;                // crea un input MIDI MidiMsg msg_in;             // crea un contenitore per i messaggi MIDI ricevuti /*    seleziona la porta MIDI che corrisponde al    controller in uso (CTRL+2 per controllare le porte MIDI) */ "Launchkey MK2 25 MIDI 1" => string device_name; m_in.open( device_name ); // variabili 144 => int NOTE_ON; 128 => int NOTE_OFF; 176 => int CTRL_CHANGE; 0   => int MIDI_CHANNEL;  // canale MIDI - range da 0 a 15 float fr; float amp; int midi_note; int last_note; 0.007874016 => float divided_by_127; 0.05        => float freq_interpolation;    // in secondi [21,22,23,24,25,26,27,28] @=> int knobs[];  // control change corrispondenti agli 8 potenziometri presenti sul controller 0.1 => amp; master.gain( amp );                  // impostare l'ampiezza del Gain 'master' 10::ms  => dur attack_time;          // tempo di attacco 500::ms => dur release_time;         // tempo di rilascio line.time( freq_interpolation );     // imposta il tempo di interpolatione della frequenza dell'oscillatore <<< "Basic Mono Synth with Sine, Square, Triangle and Sawtooth oscillators" >>>; <<< "waveform: " + waveform_name[ selected_oscil ] >>>; // loop infinito while( true ) {    // avanza ad ogni messaggio MIDI ricevuto    m_in => now;    while( m_in.recv( msg_in ) )    {        if( msg_in.data1 == ( NOTE_ON + MIDI_CHANNEL ) && msg_in.data3 != 0 )        {            // resetta il volume prima di generare una nuova nota per evitare 'glitch'            env.duration( 3::ms );            env.keyOff(1);            3::ms => now;            msg_in.data2 => midi_note;            set_oscils( midi_note );        // seleziona la wavetable in base alla nota ricevuta e l'oscillatore selezionato            Std.mtof( midi_note ) => fr;    // conversione da MIDI a Freq in Hz            line.target( fr );              // assegnare la frequenza a 'line' che controlla la freq dell'oscillatore            msg_in.data2 => last_note;            msg_in.data3 * divided_by_127 => float amplitude;            env.gain( amplitude );            env.duration( attack_time );            env.keyOn(1);        }        // controlla che il messaggio MIDI sia un NOTE OFF o un NOTE ON con velocity 0        // in entrambi i casi la nota MIDI deve combaciare con l'ultima suonata (playedNote)        else if( ( msg_in.data1 == ( NOTE_ON + MIDI_CHANNEL ) && msg_in.data3 == 0 && msg_in.data2 == last_note )                  || ( msg_in.data1 == ( NOTE_OFF + MIDI_CHANNEL ) && msg_in.data2 == last_note ) )        {            env.duration( release_time );            env.keyOff(1);        }        // portamento        else if( msg_in.data1 == ( CTRL_CHANGE+MIDI_CHANNEL ) && msg_in.data2 == knobs[0] )        {            set_interp( msg_in.data3 ) => freq_interpolation;            line.time( freq_interpolation );        }        // seleziona la forma d'onda        else if( msg_in.data1 == ( CTRL_CHANGE+MIDI_CHANNEL ) && msg_in.data2 == knobs[1] )        {            msg_in.data3 * 4 => int x;            x / 128 => selected_oscil;            if( selected_oscil != previous_oscil )            {                set_oscils( midi_note );        // seleziona la wavetable in base alla nota ricevuta e l'oscillatore selezionato                <<< "waveform: " + waveform_name[ selected_oscil ] >>>;                selected_oscil => previous_oscil;            }        }    } } // -------------FUNZIONI-------------- function float set_interp( float x ) {    x * divided_by_127 => x;        // scala in un range da 0 a 1    x * x * x => x;                 // rendi la funzione esponenziale    ( x * 0.997 ) + 0.003 => x;     // scala in un range da 3 a 1000 millisecondi    <<< "Freq Interpolation: " + x + " sec" >>>;    return x; } function void set_oscils( int x ) {    /*        Seleziona l'UGen Gen10 in base alla nota ricevuta.        I diversi Gen10 hanno un diverso numero di armoniche,        piu' e' alta la nota selezionata meno armoniche si avranno        per evitare problemi di aliasing    */    0 => int pointer;     // utilizzato come puntatore per l'array 'oscils'    // quando l'oscillatore selezionato NON e' sinusoidale    if( selected_oscil > 0 )    {        ( ( selected_oscil - 1 ) * 4 ) + 1 => pointer;        if( x <= 70 && oscils[ pointer ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == pointer )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }        else if(  x > 70 && x <= 90 && oscils[ pointer + 1 ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == ( pointer + 1 ) )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }        else if( x > 90 && x <= 108 && oscils[ pointer + 2 ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == ( pointer + 2 ) )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }        else if( x > 108 && x <= 127 && oscils[ pointer + 3 ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == ( pointer + 3 ) )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }    }    // quando l'oscillatore selezionato e' sinusoidale    else if( selected_oscil == 0 )    {        if( oscils[ pointer ].isConnectedTo( env ) == 0 )        {            for( 0 => int c; c < oscils.size(); c++ )            {                if( c == pointer )                {                    phasor => oscils[c] => env;                }                else                {                    phasor =< oscils[c] =< env;                }            }        }    } } function void init_oscils() {    /*        Inizializza l'array di Gen10 'oscils'.        Il primo elemento dell'array e' una sinusoide, a seguire si ha        onda quadra, triangolare e dente di sega, le quali utilizzano        4 Gen10 ognuna.    */    float coefficients[0];            // coefficienti degli UGen Gen10    // onda sinusoidale - oscils[0]    coefficients.size(1);    1 => coefficients[0];    oscils[0].coefs( coefficients );    // onda quadra - formula: y = sum[(1/k)*sin(2PI*f*k*t)]; con k=1,3,5,7,9,...    // quadra: 14 parziali - oscils[1]    for( 1 => int c; c < 15; c++ )    {        ( ( c * 2 ) - 1 ) => int odd; // solo numeri dispari        coefficients.size( odd );     // ridimensiona l'array        1. / odd => float amp;        // 1/n        amp => coefficients[ odd-1 ];    }    oscils[1].coefs( coefficients );    // quadra: 7 parziali - oscils[2]    for( 1 => int c; c < 8; c++ )    {        ( ( c * 2 ) - 1 ) => int odd;        coefficients.size( odd );        1. / odd => float amp;        amp => coefficients[ odd-1 ];    }    oscils[2].coefs( coefficients );    // quadra: 3 parziali - oscils[3]    for( 1 => int c; c < 4; c++ )    {        ( ( c * 2 ) - 1 ) => int odd;        coefficients.size( odd );        1. / odd => float amp;        amp => coefficients[ odd-1 ];    }    oscils[3].coefs( coefficients );    // quadra: 1 parziale - sinusoide - oscils[4]    for( 1 => int c; c < 2; c++ )    {        ( ( c * 2 ) - 1 ) => int odd;        coefficients.size( odd );        1. / odd => float amp;        amp => coefficients[ odd-1 ];    }    oscils[4].coefs( coefficients );    // onda triangolare - formula: y = sum[(1/k^2)*sin(2PI*f*k*t + theta)]; con k=1,3,5,7,9,... e theta=0,180,0,180 in gradi    // triangolare: 14 parziali - oscils[5]    for( 1 => int c; c < 15; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[5].coefs( coefficients );    // triangolare: 7 parziali - oscils[6]    for( 1 => int c; c < 8; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[6].coefs( coefficients );    // triangolare: 3 parziali - oscils[7]    for( 1 => int c; c < 4; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[7].coefs( coefficients );    // triangolare: 1 parziale - sinusoide - oscils[8]    for( 1 => int c; c < 2; c++ )    {        float theta;        /*            theta=0 quando c e' dispari, theta=180 quando c e' pari.            La fase viene espressa attraverso l'ampiezza. Ampiezza positiva quando theta=0,            ampiezza negativa quando theta=180, cioe' si ha la fase inversa.        */        if( ( c % 2 ) == 1 )        {            1 => theta;        }        else        {            -1 => theta;        }        ( ( c * 2 ) - 1 ) => int odd;                         // solo numeri dispari        coefficients.size( odd );                             // ridimensiona l'array        theta * ( 1. / ( odd * odd ) ) => float amp;          // 1/(n^2) * theta        amp => coefficients[ odd-1 ];    }    oscils[8].coefs( coefficients );    // onda a dente di sega - formula: y = sum[(1/k)*sin(2PI*f*k*t)]; con k=1,2,3,4,5,...    // dente di sega: 14 parziali - oscils[9]    for( 1 => int c; c < 15; c++ )    {        coefficients.size( c );       // ridimensiona l'array        ( 1. / c ) => float amp;      // 1/n        amp => coefficients[ c-1 ];    }    oscils[9].coefs( coefficients );    // dente di sega: 7 parziali - oscils[10]    for( 1 => int c; c < 8; c++ )    {        coefficients.size( c );       // ridimensiona l'array        ( 1. / c ) => float amp;      // 1/n        amp => coefficients[ c-1 ];    }    oscils[10].coefs( coefficients );    // dente di sega: 3 parziali - oscils[11]    for( 1 => int c; c < 4; c++ )    {        coefficients.size( c );      // ridimensiona l'array        ( 1. / c ) => float amp;     // 1/n        amp => coefficients[ c-1 ];    }    oscils[11].coefs( coefficients );    // dente di sega: 1 parziale - sinusoide - oscils[12]    for( 1 => int c; c < 2; c++ )    {        coefficients.size( c );      // ridimensiona l'array        ( 1. / c ) => float amp;     // 1/n        amp => coefficients[ c-1 ];    }    oscils[12].coefs( coefficients ); } // _FUNZIONI
RIEPILOGO
generatori d'onda triangolare, dente di sega (limitati in banda)
array di UGen
perfezionamento dell'algoritmo di gestione degli oscillatori
Il codice ed il testo possono essere scaricati qui: https://bitbucket.org/mariobuoninfante/chuck_workshop/src
0 notes
marcogiovenale · 3 years ago
Text
elementi sul festival di pari & dispari, cavriago 1977
elementi sul festival di pari & dispari, cavriago 1977
qualche elemento sul FESTIVAL TENDENZE D’ARTE INTERNAZIONALE – PARI & DISPARI [ PERFORMANCE, CONCERTI FLUXUS, ESPOSIZIONI A CAVRIAGO ] 19 – 20 Marzo 1977 https://slowforward.net/2020/09/18/16-20-marzo-1977-cavriago-reggio-emilia-festival-tendenze-darte-internazionale/ con una apparizione improvvisa e fragorosa di Emilio Villa accanto a Corrado Costa, da 9′ 47” a 10′ 26” : “distruggere il potere…
View On WordPress
0 notes
marcogiovenale · 3 years ago
Text
2 partizioni di mesens (una "di" giulio bizzarri)
2 partizioni di mesens (una “di” giulio bizzarri)
Edouard Léon Théodore Mesens La partition complète complétée 1945 (fonte: http://pearoid.unblog.fr/2019/04/07/simon-watson-taylor-1923-2005-revue-n1-unique-parution-free-unions/) cliccare per ingrandire e la stessa opera, inserita come negativo nella cartella di Giulio Bizzarri, Musica, Edizione Teatro Municipale di Reggio Emilia, 1973: cliccare per ingrandire * fonte, per la…
Tumblr media
View On WordPress
1 note · View note
marcogiovenale · 3 years ago
Text
scompare l'artista giovanni rubino
scompare l’artista giovanni rubino
Giovanni Rubino (1938) è scomparso a Milano. Artista energicamente impegnato, aveva collaborato fittamente con Corrado Costa. Qui un articolo su Artribune: artribune.com/arti-visive/arte-contemporanea/2021/10/giovanni-rubino-artista-rip/ Qui la pagina a lui dedicata nell’archivio Pari&Dispari di Rosanna Chiessi: pariedispari.org/artisti/rubino-giovanni con immagini, documenti, materiali e link di…
View On WordPress
0 notes
marcogiovenale · 4 years ago
Text
7 aprile e 5 maggio: pari&dispari 1971-2021. arte internazionale a cavriago
7 aprile e 5 maggio: pari&dispari 1971-2021. arte internazionale a cavriago
Pari&Dispari 1971-2021. Arte internazionale a Cavriago a cura di Silvia Fantini Il Multiplo Centro Cultura Cavriago, con il patrocinio del Comune di Cavriago, propone la rassegna di appuntamenti Pari&Dispari 1971-2021. Arte internazionale a Cavriago in occasione dei cinquant’anni dalla fondazione della casa editrice Pari&Dispari ad opera di Rosanna Chiessi. Rosanna Chiessi (Latina, 1934 – Reggio…
Tumblr media
View On WordPress
0 notes
marcogiovenale · 4 years ago
Text
7 aprile e 5 maggio: incontri su rosanna chiessi e su pari & dispari
7 aprile e 5 maggio: incontri su rosanna chiessi e su pari & dispari
Fluxus, arte, materiali verbovisivi, incontri, performance
Tumblr media
View On WordPress
0 notes
marcogiovenale · 4 years ago
Text
sinfonia per fischietto _ dedicata ai fossili / corrado costa. 1990
sinfonia per fischietto _ dedicata ai fossili / corrado costa. 1990
  fonte: https://www.pariedispari.org/opere/corrado-costa-opere-collage _
Tumblr media
View On WordPress
0 notes