Semplice Sinth MIDI

MidiSinthDeviceService.java

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.midisynth;

import android.media.midi.MidiDeviceService;
import android.media.midi.MidiDeviceStatus;
import android.media.midi.MidiReceiver;

import com.example.android.common.midi.synth.SynthEngine;

public class MidiSynthDeviceService extends MidiDeviceService {

    private SynthEngine mSynthEngine = new SynthEngine();
    private boolean mSynthStarted = false;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        mSynthEngine.stop();
        super.onDestroy();
    }

    @Override
    public MidiReceiver[] onGetInputPortReceivers() {
        return new MidiReceiver[]{mSynthEngine};
    }

    /**
     * This will get called when clients connect or disconnect.
     */
    @Override
    public void onDeviceStatusChanged(MidiDeviceStatus status) {
        if (status.isInputPortOpen(0) && !mSynthStarted) {
            mSynthEngine.start();
            mSynthStarted = true;
        } else if (!status.isInputPortOpen(0) && mSynthStarted) {
            mSynthEngine.stop();
            mSynthStarted = false;
        }
    }

}

MainActivity.java

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.midisynth;

import android.content.pm.PackageManager;
import android.media.midi.MidiDevice.MidiConnection;
import android.media.midi.MidiDeviceInfo;
import android.media.midi.MidiManager;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.Toast;

import com.example.android.common.midi.MidiOutputPortConnectionSelector;
import com.example.android.common.midi.MidiPortConnector;
import com.example.android.common.midi.MidiTools;

/**
 * Simple synthesizer as a MIDI Device.
 */
public class MainActivity extends AppCompatActivity {

    private MidiOutputPortConnectionSelector mPortSelector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayShowTitleEnabled(false);
        }

        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI)) {
            setupMidi();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        setKeepScreenOn(menu.findItem(R.id.action_keep_screen_on).isChecked());
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_keep_screen_on:
                boolean checked = !item.isChecked();
                setKeepScreenOn(checked);
                item.setChecked(checked);
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void setKeepScreenOn(boolean keepScreenOn) {
        if (keepScreenOn) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        } else {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    }

    private void setupMidi() {
        // Setup MIDI
        MidiManager midiManager = (MidiManager) getSystemService(MIDI_SERVICE);

        MidiDeviceInfo synthInfo = MidiTools.findDevice(midiManager, "AndroidTest",
                "SynthExample");
        int portIndex = 0;
        mPortSelector = new MidiOutputPortConnectionSelector(midiManager, this,
                R.id.spinner_synth_sender, synthInfo, portIndex);
        mPortSelector.setConnectedListener(new MyPortsConnectedListener());
    }

    private void closeSynthResources() {
        if (mPortSelector != null) {
            mPortSelector.close();
        }
    }

    // TODO A better way would be to listen to the synth server
    // for open/close events and then disable/enable the spinner.
    private class MyPortsConnectedListener
            implements MidiPortConnector.OnPortsConnectedListener {
        @Override
        public void onPortsConnected(final MidiConnection connection) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (connection == null) {
                        Toast.makeText(MainActivity.this,
                                R.string.error_port_busy, Toast.LENGTH_SHORT)
                                .show();
                        mPortSelector.clearSelection();
                    } else {
                        Toast.makeText(MainActivity.this,
                                R.string.port_open_ok, Toast.LENGTH_SHORT)
                                .show();
                    }
                }
            });
        }
    }

    @Override
    public void onDestroy() {
        closeSynthResources();
        super.onDestroy();
    }

}

profMI

# profMI.py
#
# 
# Il professor MII insegna in una classe universitaria formata da
# ragazzi e ragazze. Viene fornita una lista contenente una lista 
# per ogni studente. Il primo numero della lista è l'idendificativo
# dello studente, il secondo numero della lista rappresenta il sesso;
# (0=MASCHIO,1=FEMMINA,2=LGBT). I restanti numeri indicano i voti
# conseguiti per quello studente.
# Il programma determina la media dei voti per genere sessuale.
#
# by Andrea Bianchini (2021)

from random import randint

N = 50
MIN = 18
MAX = 31
NVOTI = 5

#generazione casuale lista dei voti:
cl=[]
for i in range(N):
    student=[]
    student.append(i)
    student.append(randint(0,2))
    for j in range(NVOTI):
        student.append(randint(MIN,MAX))
    cl.append(student)
                   
#calcolo
mediatot=[0.0,0.0,0.0]
ng=[0,0,0]
for i in range(N):
    medias=[0.0,0.0,0.0]
    student=cl[i]
    sex = student[1]
    ng[sex]+=1
    for j in range(NVOTI):
        medias[sex]+=float(student[2+j])
    medias[sex]/=float(NVOTI)
    mediatot[sex]+=medias[sex]

mediatot[0]/=float(ng[0])
mediatot[1]/=float(ng[1])
mediatot[2]/=float(ng[2])

print("Lista studenti = ", cl)
print()
print("Media voti maschi = %.2f" %mediatot[0])
print("Media voti femmine = %.2f" %mediatot[1])
print("Media voti LGBT = %.2f" %mediatot[2])

Esempio:

Lista studenti =  [[0, 0, 23, 23, 22, 24, 28], [1, 0, 22, 18, 18, 24, 28], [2, 0, 30, 25, 28, 21, 25], [3, 1, 23, 18, 23, 24, 30], [4, 0, 23, 19, 23, 25, 30], [5, 0, 19, 24, 30, 29, 26], [6, 1, 19, 21, 21, 20, 22], [7, 1, 27, 30, 18, 26, 20], [8, 1, 30, 24, 29, 21, 23], [9, 2, 31, 19, 27, 30, 25], [10, 2, 31, 27, 21, 31, 22], [11, 1, 19, 25, 19, 31, 20], [12, 2, 29, 24, 24, 26, 29], [13, 0, 26, 23, 25, 26, 29], [14, 0, 25, 29, 23, 21, 29], [15, 0, 19, 28, 22, 20, 29], [16, 1, 28, 21, 24, 22, 18], [17, 2, 19, 22, 27, 25, 22], [18, 1, 31, 22, 18, 27, 20], [19, 2, 21, 25, 25, 19, 23], [20, 2, 27, 23, 30, 25, 21], [21, 1, 26, 29, 23, 30, 30], [22, 1, 29, 22, 18, 30, 26], [23, 0, 23, 30, 28, 20, 19], [24, 1, 27, 29, 28, 19, 29], [25, 0, 25, 27, 22, 24, 31], [26, 1, 30, 26, 28, 26, 28], [27, 0, 18, 22, 30, 27, 26], [28, 1, 27, 18, 25, 24, 18], [29, 0, 31, 23, 24, 21, 30], [30, 2, 30, 28, 19, 24, 25], [31, 2, 23, 22, 23, 22, 19], [32, 2, 29, 31, 30, 25, 29], [33, 1, 30, 21, 29, 20, 23], [34, 1, 21, 26, 27, 23, 18], [35, 1, 29, 25, 20, 29, 25], [36, 2, 18, 21, 20, 22, 31], [37, 1, 30, 20, 19, 26, 20], [38, 0, 26, 19, 22, 22, 19], [39, 0, 31, 27, 19, 29, 18], [40, 2, 26, 26, 23, 24, 21], [41, 2, 28, 26, 23, 22, 25], [42, 2, 29, 27, 29, 25, 24], [43, 1, 29, 21, 18, 31, 29], [44, 1, 24, 22, 20, 31, 21], [45, 1, 20, 21, 30, 28, 23], [46, 0, 26, 24, 29, 26, 23], [47, 1, 22, 26, 26, 31, 26], [48, 2, 18, 23, 25, 23, 21], [49, 0, 18, 22, 26, 23, 23]]

Media voti maschi = 24.43
Media voti femmine = 24.39
Media voti LGBT = 24.70
>>> 

Coppie di numeri a differenza costante

# kdiff.py
#
# 
# Questo programma risolve il seguente problema :
# Dato un insieme s di N numeri interi trovare
# tutte le coppie di interi la cui differenza è pari a K
#
# by Andrea Bianchini (2021)

from random import randint

N = 50
MIN = 1
MAX = 1000
K = randint(MIN,MAX/2)

s = [randint(MIN,MAX) for _ in range(N)]


def f(x,y):
    global K
    if abs(x-y)==K:
        return True
    else:
        return False
    
res =[]

for x in range(N-1):
    for y in range(x+1,N):
        if f(s[x],s[y]):
            res.append((s[x],s[y]))

print("s =",s)
print()
print("K = %d" %K)
print("coppie =",res)

Esempio 1:

s = [240, 662, 961, 108, 802, 232, 954, 99, 542, 775, 668, 988, 637, 96, 135, 549, 111, 678, 86, 596, 912, 13, 191, 516, 118, 88, 837, 632, 870, 843, 542, 569, 819, 579, 411, 154, 743, 89, 95, 686, 604, 503, 511, 859, 305, 671, 161, 510, 164, 906]

K = 10
coppie = [(108, 118), (99, 89), (668, 678), (96, 86), (569, 579), (154, 164)]
>>> 

Esempio 2:

s = [327, 847, 660, 722, 431, 287, 79, 542, 354, 514, 703, 522, 764, 75, 904, 789, 103, 801, 929, 884, 964, 818, 992, 458, 369, 900, 239, 671, 120, 904, 421, 342, 403, 314, 495, 794, 119, 140, 810, 237, 333, 639, 676, 705, 134, 802, 528, 20, 452, 2]

K = 105
coppie = [(239, 134), (342, 237), (810, 705)]
>>> 

Odore del silenzio

Odore del silenzio, by Andrea Bianchini (2021)

……………..

Odore del silenzio

Sento l’odore del silenzio, tutt’intorno.
Lievi aliti di arie che foglie non muovono.
Ambita meta oramai rinunciata e mai raggiunta,
sublima nella tua espressione, nella tua gestualità,
nei tuoi passi armonicamente ancheggianti e sensuali.

Cerchiamo riparo, da questo caos intangibile,
nulla è più importante, oramai, se non la pace.
E tu l’hai trovata, in altra vita ed altre sembianze,
assaporando il tuo ormai etereo passato come un digestivo.
Rimani ancora un attimo con me e vibrami il tuo soave volto.

Mille vite non bastano a percorrerle per comprendere,
e saggiare il sapore dello strazio, della miseria.
Accheta la mia inquietudine con un tuo sguardo, semplicemente,
e congedati da me in quella direzione, ove ti indico,
si che io mi possa addormentare con un lieve sorriso in volto.


Smell of silence

I can smell the silence all around.
Slight breaths of air that leaves do not move.
A sought-after goal now renounced and never reached,
sublime in your expression, in your gestures,
in your harmoniously swaying and sensual steps.

We seek shelter from this intangible chaos
nothing is more important now than peace.
And you found it, in another life and other semblances,
savoring your now ethereal past like a digestive.
Stay with me a moment longer and your sweet face vibrate me.

A thousand lives are not enough to walk them to understand,
and test the taste of agony, of misery.
Accheta my restlessness with a look from you, simply,
and take leave of me in that direction, where I show you,
so that I can fall asleep with a slight smile on my face.

by Andrea Bianchini

A minimal App in Android

In questo post vi mostro la struttura minimale di una App Android. In realtà potrebbe essere resa ancora più semplice, ma non chiarirebbe bene quali sono le parti che costituiscono l’App.

Iniziamo con il file AndroidManifest.xml (directory app/manifests) :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.andreabianchini.simpleandroidapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SimpleAndroidApp">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Passiamo al file che contiene il programma principale dell’App, MainActivity.java (directory app/java) :

package com.andreabianchini.simpleandroidapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Al programma (Activity) principale sopra riportato viene associato un file di risorse, activity_main.xml, (directory app/res/layout), che serve a definire l’aspetto ed i contenuti grafici della schermata associata all’attività principale :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

In questo caso la nostra App Android minimale visualizzerà una schermata con la scritta : ‘Hello World!’.

Con l’ambiente di sviluppo ‘Android Studio’ potete generare automaticamente questa applicazione in un minuto.

Ecco il risultato:

App Android minimale

Catch the note

In questo articolo rendo pubblico, a titolo di esempio, il codice java principale della mia app CatchTheNote, disponibile in versione completa alla voce di menù Android.

package com.andreabianchini.catchthenote;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.text.InputFilter;
import android.text.Spanned;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;

import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private SoundPool soundPool;
    private int soundID,tone;
    private int a,as,b,c,cs,d,ds,e,f,fs,g,gs;
    boolean plays = false, loaded = false;
    float actVolume, maxVolume, volume;
    AudioManager audioManager;
    int counter;
    int [] notes=new int[8];
    int [] notesId=new int[8];
    int nnotes=1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // AudioManager audio settings for adjusting the volume
        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        actVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        volume = actVolume / maxVolume;

        //Hardware buttons setting to adjust the media sound
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

        // the counter will help us recognize the stream id of the sound played  now
        counter = 0;

        // Load the sounds
        soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
        soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                loaded = true;
                plays=false;
            }
        });

        a = soundPool.load(this, R.raw.a, 1);
        as = soundPool.load(this, R.raw.as, 1);
        b = soundPool.load(this, R.raw.b, 1);
        c = soundPool.load(this, R.raw.c, 1);
        cs = soundPool.load(this, R.raw.cs, 1);
        d = soundPool.load(this, R.raw.d, 1);
        ds = soundPool.load(this, R.raw.ds, 1);
        e = soundPool.load(this, R.raw.e, 1);
        f = soundPool.load(this, R.raw.f, 1);
        fs = soundPool.load(this, R.raw.fs, 1);
        g = soundPool.load(this, R.raw.g, 1);
        gs = soundPool.load(this, R.raw.gs, 1);

        soundID = a;
        nnotes=1;
        notes[0]=0;
        notesId[0]=a;

        Button button =  findViewById(R.id.btPlay);
        Button button1 =  findViewById(R.id.btA);
        Button btChange =  findViewById(R.id.btChange);
        Button btShow =  findViewById(R.id.btShow);
        Button btInfo =  findViewById(R.id.btInfo);
        EditText etNNotes = findViewById(R.id.etNNotes);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playSound(v);
           }
        });

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playA(v);
            }
        });

        btChange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                changeNote(v);
            }
        });

        btShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showNote(v);
            }
        });

        btInfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showInfo(v);
            }
        });

        etNNotes.setFilters(new InputFilter[]{ new InputFilterMinMax("1", "8")});

        // Initialize the Mobile Ads SDK
        MobileAds.initialize(this, getString(R.string.admob_app_id));

        AdView mBannerAd;

        mBannerAd = findViewById(R.id.adView);

        AdRequest adRequest = new AdRequest.Builder()
                .build();
        mBannerAd.loadAd(adRequest);

    }

    public void showInfo(View v) {
        Intent intent = new Intent(MainActivity.this, Info.class);
        startActivity(intent);

    }

    public void showNote(View v) {
        TextView tv  =  findViewById(R.id.tvNote);
        EditText etNNotes = findViewById(R.id.etNNotes);
        nnotes = Integer.parseInt(etNNotes.getText().toString());
        String s;
        s="";
        for(int i=0;i<nnotes;i++) {
            switch (notes[i]) {
                case 0:
                    s+="A ";
                    break;
                case 1:
                    s+="A# ";
                    break;
                case 2:
                    s+="B ";
                    break;
                case 3:
                    s+="C ";
                    break;
                case 4:
                    s+="C# ";
                    break;
                case 5:
                    s+="D ";
                    break;
                case 6:
                    s+="D# ";
                    break;
                case 7:
                    s+="E ";
                    break;
                case 8:
                    s+="F ";
                    break;
                case 9:
                    s+="F# ";
                    break;
                case 10:
                    s+="G ";
                    break;
                case 11:
                    s+="G# ";
                    break;

            }
        }
        tv.setText(s);
    }

    public void changeNote(View v) {
        EditText etNNotes = findViewById(R.id.etNNotes);
        nnotes = Integer.parseInt(etNNotes.getText().toString());
        int last,last1;
        last1=2;
        last=1;
        for(int i=0;i<nnotes;i++) {
            tone=0;
            if (i>1)
            while(tone==last || (Math.abs(tone-last)==1 && Math.abs(last1-last)==1) || (Math.abs(tone-last)==3 && Math.abs(last1-last)==3) || (Math.abs(tone-last)==2 && Math.abs(last1-last)==3) || (Math.abs(tone-last)==3 && Math.abs(last1-last)==2)) {
                tone = new Random().nextInt(12);
            }
            else
                tone = new Random().nextInt(12);
            last1 = last;
            last = tone;
            notes[i]=tone;
            switch (tone) {
                case 0:
                    soundID = a;
                    break;
                case 1:
                    soundID = as;
                    break;
                case 2:
                    soundID = b;
                    break;
                case 3:
                    soundID = c;
                    break;
                case 4:
                    soundID = cs;
                    break;
                case 5:
                    soundID = d;
                    break;
                case 6:
                    soundID = ds;
                    break;
                case 7:
                    soundID = e;
                    break;
                case 8:
                    soundID = f;
                    break;
                case 9:
                    soundID = fs;
                    break;
                case 10:
                    soundID = g;
                    break;
                case 11:
                    soundID = gs;
                    break;

            }
            notesId[i]=soundID;
        }
    }

    public void playSound(View v) {
        // Is the sound loaded does it already play?
        TextView tv  =  findViewById(R.id.tvNote);
        tv.setText(getString(R.string.note));

        for (int i=0;i<nnotes;i++){
        if (loaded && !plays) {
            soundPool.play(notesId[i], 1, 1, 0, 0, 1);
            counter = counter++;
            //Toast.makeText(this, "Played sound", Toast.LENGTH_SHORT).show();
            //plays = true;
        }
            try { Thread.sleep(1600); }
            catch (InterruptedException ex) { android.util.Log.d("Catch the Note", ex.toString()); }        }
    }

    public void playA(View v) {
        // Is the sound loaded does it already play?
        TextView tv  =  findViewById(R.id.tvNote);
        tv.setText(getString(R.string.note));

            if (loaded && !plays) {
                soundPool.play(a, 1, 1, 0, 0, 1);
                counter = counter++;
                //Toast.makeText(this, "Played sound", Toast.LENGTH_SHORT).show();
                //plays = true;
            }
            try { Thread.sleep(1600); }
            catch (InterruptedException ex) { android.util.Log.d("Catch the Note", ex.toString()); }
    }

    public void playLoop(View v) {
        // Is the sound loaded does it already play?
        if (loaded && !plays) {

            // the sound will play for ever if we put the loop parameter -1
            soundPool.play(soundID, volume, volume, 1, -1, 1f);
            counter = counter++;
            Toast.makeText(this, "Plays loop", Toast.LENGTH_SHORT).show();
            plays = true;
        }
    }

    public void pauseSound(View v) {
        if (plays) {
            soundPool.pause(soundID);
//            soundID = soundPool.load(this, R.raw.beep, counter);
            Toast.makeText(this, "Pause sound", Toast.LENGTH_SHORT).show();
            plays = false;
        }
    }

    public void stopSound(View v) {
        if (plays) {
            soundPool.stop(soundID);
//            soundID = soundPool.load(this, R.raw.beep, counter);
            Toast.makeText(this, "Stop sound", Toast.LENGTH_SHORT).show();
            plays = false;
        }
    }

    public class InputFilterMinMax implements InputFilter {

        private int min, max;

        public InputFilterMinMax(int min, int max) {
            this.min = min;
            this.max = max;
        }

        public InputFilterMinMax(String min, String max) {
            this.min = Integer.parseInt(min);
            this.max = Integer.parseInt(max);
        }

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            try {
                int input = Integer.parseInt(dest.toString() + source.toString());
                if (isInRange(min, max, input))
                    return null;
            } catch (NumberFormatException nfe) { }
            return "";
        }

        private boolean isInRange(int a, int b, int c) {
            return b > a ? c >= a && c <= b : c >= b && c <= a;
        }
    }
    }

Doppio verso

Doppio Verso by Andrea Bianchini

……………..

Doppio verso

Di quel mondo, annientato, cancellato,
poco sappiamo.
Vennero ere, civiltà e tutte,
ad un certo punto, terminarono il loro ciclo.

Rimasero i ruderi, a volte gli scritti,
ogni volta in lingue sconosciute.
Quante volte la vita viene interrotta…
Stop; e tutto si ferma.

Questo succede alle persone, alle comunità,
alle città, alle nazioni, ai mondi; alle stelle.
Ma ogni volta gli unici superstiti
sono gli animali, di alcune specie,
e la natura; le piante, l’acqua, il fuoco, i venti…

Ebbene, quel mondo venne annientato da una malattia
che colpì tutti, di sesso ed età diversi,
e questa malattia è capace di viaggiare nei due versi del tempo,
nel passato e nel futuro, senza danno subire.

e così cominciarono a sparire oggetti e persone,
come conseguenza della morte dell’inventore
prima che questi pubblicasse la scoperta.
Ed anche cominciarono a comparire oggetti e persone strani.

Interi palazzi svanivano in un batter d’occhio,
comparivano strani oggetti all’interno delle case,
persone bizzarre come i loro vestiti camminavano per strada.
tutto si mischiò, furono il caos e l’incomprensione totale.

…………………..

Double verse

Of that world, annihilated, erased,
little we know.
Ages came, civilizations and all,
at some point, they ended their cycle.

The ruins remained, sometimes the writings,
each time in unknown languages.
How many times life is interrupted …
Stop; and everything stops.

This happens to people, communities,
to cities, nations, worlds; to the stars.
But each time the only survivors
are the animals, of some species,

It’s the nature; plants, water, fire, winds …
Well, that world was annihilated by a disease
which affected everyone, of different sexes and ages,
and this disease is capable of traveling in both directions of time,
in the past and in the future, without suffering harm.

and so objects and people began to disappear,
as a consequence of the inventor’s death
before he published the discovery.
And also strange objects and people began to appear.

Entire buildings vanished in the blink of an eye,
strange objects appeared inside the houses,
bizarre people like their clothes walked down the street.
everything mixed up, it was chaos and total misunderstanding.

by Andrea Bianchini

Abbracciami

Abbracciami – Testo, musica ed esecuzione by Andrea Bianchini

………………….

Abbracciami

Mi avresti dato del tu,
perbacco… e la tua venere prediletta ?
Accipicchia, non sono solo,
qualcuno sta ascoltando e forse, vedendo.

Dammi la tua mano, per contare le rughe,
no, non la so leggere ma ho visioni di te.
Recami nei luoghi segreti della tua anima,
acclama il folle che è in tutti noi.

Sentieri erti pieni di ciotoli,
perchè li scorre acqua a fiumi, quando piove.
Ne ho raccolto uno, e mi ha sorriso,
subito l’ho riposto, nella sua culla.

Accetta il tuo amore per la bellezza
che pur è soggettiva, ma ci pervade le membra
di un lieve, gradito tepore, gratuitamente.
Non sono un pezzo di legno, abbracciami.

…………….

hug me

You would have called me you,
by God … and your favorite Venus?
Damn, I’m not alone
someone is listening and perhaps, seeing.

Give me your hand, to count the wrinkles,
no, I can’t read it but I have visions of you.
Go to the secret places of your soul,
acclaim the madman in all of us.

Steep paths full of pebbles,
because water flows in rivers when it rains.
I picked one up, and he smiled at me,
I immediately put it back in his cradle.

Accept your love of beauty
which is subjective, but pervades our limbs
of a light, pleasant warmth, free of charge.
I’m not a piece of wood, hug me.

Musica e testo by Andrea Bianchini

Algoritmi genetici

# DEAP_generico.py
#
# esempio di utilizzo della libreria per la computazione genetica evolutiva
# dei problemi denominata DEAP.
# in questo caso ho utilizzato lo scheletro della risoluzione di un
# problema generico per risolvere il problema di ottimizzazione
# noto come Knapsack Problem.
# documentazione su : https://deap.readthedocs.io/en/master/index.html
#
# by Andrea Bianchini (2021)



import random

from deap import base
from deap import creator
from deap import tools

IND_SIZE = 50
C = 10000
MIN_WEIGHT = int(C*0.01)
MAX_WEIGHT = int(C*0.07)
MAX=0
sol=[]
items=[random.randint(MIN_WEIGHT,MAX_WEIGHT) for _ in range(IND_SIZE)]

creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)

toolbox = base.Toolbox()
# Attribute generator 
toolbox.register("attr_bool", random.randint, 0, 1)
# Structure initializers
toolbox.register("individual", tools.initRepeat, creator.Individual, 
    toolbox.attr_bool, IND_SIZE)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

def evalOneMax(individual):
    global sol
    global MAX
    e1 = sum([items[i]*individual[i] for i in range(len(individual))])
    if e1>MAX and e1<=C:
        MAX = e1
        sol=individual
    return e1,

toolbox.register("evaluate", evalOneMax)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
toolbox.register("select", tools.selTournament, tournsize=3)

summa=0
def main():
    global summa
    pop = toolbox.population(n=300)

    # Evaluate the entire population
    fitnesses = list(map(toolbox.evaluate, pop))
    for ind, fit in zip(pop, fitnesses):
        ind.fitness.values = fit

    # CXPB  is the probability with which two individuals
    #       are crossed
    #
    # MUTPB is the probability for mutating an individual
    CXPB, MUTPB = 0.5, 0.2

    # Extracting all the fitnesses of 
    fits = [ind.fitness.values[0] for ind in pop]

    # Variable keeping track of the number of generations
    g = 0
    
    # Begin the evolution
    
    while max(fits) < C and g < 1000:
        # A new generation
        g = g + 1
        print("-- Generation %i --" % g)

        # Select the next generation individuals
        offspring = toolbox.select(pop, len(pop))
        # Clone the selected individuals
        offspring = list(map(toolbox.clone, offspring))

        # Apply crossover and mutation on the offspring
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < CXPB:
                toolbox.mate(child1, child2)
                del child1.fitness.values
                del child2.fitness.values

        for mutant in offspring:
            if random.random() < MUTPB:
                toolbox.mutate(mutant)
                del mutant.fitness.values

        # Evaluate the individuals with an invalid fitness
        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit

        pop[:] = offspring

        # Gather all the fitnesses in one list and print the stats
        fits = [ind.fitness.values[0] for ind in pop]
        
        length = len(pop)
        mean = sum(fits) / length
        sum2 = sum(x*x for x in fits)
        std = abs(sum2 / length - mean**2)**0.5
        
        print("  Min %s" % min(fits))
        print("  Max %s" % max(fits))
        print("  Avg %s" % mean)
        print("  Std %s" % std)

        if max(fits) <=C and summa<max(fits):
            summa = max(fits)

main()
print()
print("Soluzione ottima = %d" %MAX)
print("Lista items completa :")
print(items)
print("Lista items soluzione :")
osol = [items[i]*sol[i] for i in range(IND_SIZE)]
print(osol)

Esempio:

Soluzione ottima = 10000
Lista items completa :
[481, 167, 361, 111, 670, 602, 119, 331, 654, 155, 400, 227, 651, 531, 413, 134, 409, 140, 488, 457, 495, 628, 153, 632, 327, 159, 593, 633, 682, 392, 368, 526, 599, 478, 408, 315, 466, 582, 302, 172, 427, 173, 551, 673, 272, 158, 502, 269, 685, 588]
Lista items soluzione :
[0, 0, 361, 0, 670, 0, 0, 331, 654, 0, 0, 0, 651, 0, 0, 0, 409, 140, 488, 0, 0, 628, 0, 632, 327, 0, 593, 0, 682, 0, 368, 0, 0, 478, 0, 315, 0, 582, 0, 172, 427, 0, 551, 0, 272, 0, 0, 269, 0, 0]
>>> 

Valore atteso, varianza e deviazione standard

# varianza.py
#
# questo programma calcola il valore medio, la varianza
# e la deviazione standard di una lista di numeri
# interi generati casualmente.
#
# by Andrea Bianchini (2021)
#


from random import randint
import math

N = 20
MIN = 0
MAX = 1000

s = [randint(MIN,MAX) for _ in range(N)]

print("La lista generata è la seguente :")
print(s)

# Calcolo valore medio
vm=float(sum(s))
vm=vm/N

# Calcolo varianza
scarti = [(sx-vm)*(sx-vm) for sx in s]
vms = float(sum(scarti))
vms = vms/N

print()
print("Scarti quadratici lista originale : ")
print(scarti)
print()
print("Valore medio lista originale: %.2f" %vm)
print()
print("Varianza lista originale: %.2f" %vms)
print()
print("Deviazione standard lista originale: %.2f" %(math.sqrt(vms)))
print()
print("Deviazione minima lista originale: %.2f " %(math.sqrt(min(scarti))))
print()
print("Deviazione massima lista originale: %.2f " %(math.sqrt(max(scarti))))

Esempio:

La lista generata è la seguente :
[73, 801, 284, 79, 291, 425, 429, 265, 494, 330, 376, 521, 333, 162, 763, 202, 66, 462, 202, 366]

Scarti quadratici lista originale : 
[74638.23999999999, 206843.04, 3868.839999999999, 71395.84, 3047.0399999999986, 6209.440000000001, 6855.840000000002, 6593.439999999998, 21844.840000000004, 262.43999999999966, 888.0400000000006, 30555.040000000005, 174.2399999999997, 33929.64, 173722.24000000002, 20793.639999999996, 78512.04, 13409.640000000003, 20793.639999999996, 392.0400000000005]

Valore medio lista originale: 346.20

Varianza lista originale: 38736.46

Deviazione standard lista originale: 196.82

Deviazione minima lista originale: 13.20 

Deviazione massima lista originale: 454.80 
>>>