Thorsten Kimmeskamp
Published © GPL3+

Musik-Papagei

Spiel dem Calliope ein Lied vor und bring ihm bei, es nachzuspielen!

AdvancedFull instructions provided2 hours206
Musik-Papagei

Things used in this project

Hardware components

Calliope mini
Calliope mini
×1

Software apps and online services

Online Tone Generator

Story

Read more

Code

Musik-Papagei

JavaScript
let nullinie = 0
let toene = ""
let frequenzen: number[] = []
let tongrenzen: number[] = []

let aufnahmeTondauern: number[] = []
let aufnahmeTonhoehen: number[] = []
let letzteDauer = 0
let letzerTon = 0

let record = false
let playback = false

let audioPuffer: number[] = []
let anzahlPerioden = 0
let summePeriodendauern = 0
let letzterNulldurchgang = 0
let halbperiode = false
let sample = 0
let dauerPeriode = 0

let frequenz = 0
let aktuellerTon = 0


nullinie = 516
toene = "*A#HC#D#EF#G#A#HC#D#EF#G#A*"
frequenzen = [0, 220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 0]
tongrenzen = [214, 227, 240, 255, 270, 286, 303, 321, 340, 360, 381, 404, 428, 453, 480, 509, 540, 572, 606, 642, 680, 720, 762, 808, 856, 906]
aufnahmeTonhoehen = []
aufnahmeTondauern = []
letzerTon = 0
letzteDauer = 0
record = false
playback = false


input.onButtonPressed(Button.A, () => {
    if (!(playback)) {
        if (!(record)) {
            basic.setLedColor(Colors.Red)
            aufnahmeTonhoehen = []
            aufnahmeTondauern = []
            letzerTon = 0
            letzteDauer = 0
        } else {
            basic.setLedColor(basic.rgbw(
            0,
            0,
            0,
            0
            ))
        }
        record = !(record)
    }
})

input.onButtonPressed(Button.B, () => {
    record = false
    playback = true
    basic.clearScreen()
    basic.setLedColor(Colors.Green)
    for (let j = 0; j <= aufnahmeTonhoehen.length - 1; j++) {
        if (aufnahmeTondauern[j] > 0) {
            music.ringTone(frequenzen[aufnahmeTonhoehen[j]])
            basic.pause(100 * aufnahmeTondauern[j])
            music.rest(music.beat(BeatFraction.Sixteenth))
        }
    }
    playback = false
    basic.setLedColor(basic.rgbw(
    0,
    0,
    0,
    0
    ))
})

basic.forever(() => {
    audioPuffer = []
    for (let i = 0; i <= 399; i++) {
        audioPuffer.push(pins.analogReadPin(AnalogPin.MIC))
        control.waitMicros(250 - 115)
    }
    letzterNulldurchgang = 0
    anzahlPerioden = 0
    summePeriodendauern = 0
    halbperiode = false
    for (let i = 0; i <= 399; i++) {
        sample = audioPuffer[i]
        if (sample < nullinie) {
            halbperiode = true
        }
        if (halbperiode && sample > nullinie) {
            halbperiode = false
            dauerPeriode = i - letzterNulldurchgang
            letzterNulldurchgang = i
            anzahlPerioden += 1
            summePeriodendauern += dauerPeriode
        }
    }
    frequenz = anzahlPerioden * 4000 / summePeriodendauern
    aktuellerTon = 0
    while (frequenz > tongrenzen[aktuellerTon] && aktuellerTon < tongrenzen.length) {
        aktuellerTon += 1
    }
    if (record) {
        if (aktuellerTon != letzerTon) {
            aufnahmeTonhoehen.push(letzerTon)
            aufnahmeTondauern.push(letzteDauer)
            letzerTon = aktuellerTon
            letzteDauer = 0
        } else {
            letzteDauer += 1
        }
    }
})

basic.forever(() => {
    if (!(playback)) {
        if (toene.charAt(aktuellerTon) != "#") {
            basic.showString(toene.charAt(aktuellerTon))
        } else {
            basic.showString(toene.charAt(aktuellerTon - 1))
            basic.pause(400)
            basic.showString("#")
            basic.pause(400)
        }
    }
})

Credits

Thorsten Kimmeskamp

Thorsten Kimmeskamp

19 projects • 12 followers

Comments