Granska befintlig kod och kommentarer Testa loopbackfunktionen

Relevanta dokument
AVR 3 - datorteknik. Avbrott. Digitala system 15 hp. Förberedelser

Effektpedal för elgitarr

Enchipsdatorer med tillämpningar LABORATION 7, ROBOT

Laboration 5. Temperaturmätning med analog givare. Tekniska gränssnitt 7,5 p. Förutsättningar: Uppgift: Temperatur:+22 C

Träff 1 - Introduktion

Lab lanserade R.A. Moog Inc. en ny synt: Minimoog. Den var designad av Bill Hemsath och Robert Moog och kom att revolutionera musikhistorien.

Datorteknik 2 (AVR 2)

PROJEKT LJUD. KOPIERINGSUNDERLAG Martin Blom Skavnes, Staffan Melin och Natur & Kultur Programmera i teknik ISBN

Studera databladen för LCD på sid 4, 5, 7, 8, 14, 18, 19, 20 och 23. Datablad finns på kurshemsidan.

PROJEKT STAFFAN STALLEDRÄNG

Laboration 4: Knappstuds Drivrutiner för att eliminera störningar.

JavaScript del 3 If, Operatorer och Confirm

Ett urval D/A- och A/D-omvandlare

Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp

22/02/16. Arduino Introduktion till Arduino. Arduino. Microcontroller - Embedded systems. Historia Organisation - Ekosystem

Elektro och Informationsteknik LTH. Laboration 6 A/D- och D/A-omvandling. Elektronik för D ETIA01

Digitala Projekt (EITF11)

AVR 5. Styrning av trafikljus. Digitala system 15 p

Enchipsdatorns gränssnitt mot den analoga omvärlden

Signalbehandling Röstigenkänning

Design av inbyggda system

TNMK054 - LJUDTEKNIK 1 RUM, REVERB,

LEU240 Mikrodatorsystem Laboration 2: Ett komplett avbrottsstyrt system med in- och utenheter

TUTORIAL: SAMLING & KONSOLL

Projekt EITA15. Väckarklocka. LTH Ingenjörshögskolan vid Campus Helsingborg Datateknik

Växtviskaren EITF11 Digitala projekt VT15, I12

Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp

Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp

IKUSI STG Produktöversikt

Grunderna i stegkodsprogrammering

Innehållsförteckning. Figur- och tabellförteckning. Figure 1 Blockschema över hårdvaran...4 Figure 2 Blockschema över programet...

Introduktion till Arduino

Design av inbyggda system

Introduktion till Arduino

- Digitala ingångar och framförallt utgångar o elektrisk modell

Övningsuppgifter till föreläsning 2 Variabler och uttryck

Robotfotboll med Arduino

Faltningsreverb i realtidsimplementering

Projektlaboration 4, synkronisering av klockan

Konstruktion av en radiostyrd legobil. Digitala projekt av Arbon Vata Leonardo Vukmanovic Amid Bhatia

Styrteknik: MELSEC FX och numeriska värden

Systemkonstruktion LABORATION REALTIDSPROGRAMMERING

CPU. Carry/Borrow IX. Programräknare

Enchipsdatorns gränssnitt mot den analoga omvärlden

TEMPERATUR OCH VINDMÄTARE MED HÖGTALARFUNKTION

Digitala projekt, EDI021 Rapport Handledare: Bertil Lindvall

Moment 1 - Analog elektronik. Föreläsning 3 Transistorförstärkare

TENTAMEN Datorteknik (DO2005) D1/E1/Mek1/Ö1

Experiment med schmittrigger

Att använda pekare i. C-kod

Design av inbyggda system

Digitala kretsars dynamiska egenskaper

Systemkonstruktion SERIEKOMMUNIKATION

Mixern. Ingångskanal. Vi tänker oss att vi ska följa signalen genom en typisk mixer, från mikrofon till utgång.

Kapitel 2 o 3 Information och bitar Att skicka signaler på en länk. Jens A Andersson

Datorprojekt, del 1. Digitala system 15 p

Tentamen PC-teknik 5 p Lösningar och kommentarer

Spänningsstyrd Oscillator

KUNGLIGA TEKNISKA HÖGSKOLAN. Linefollower. Med LEGO Mindstorms och NXC. Paul Coada Introduktion i datateknik II1310

Kapitel 2 o 3 Information och bitar Att skicka signaler på en länk. Att sända information mellan datorer. Information och binärdata

Moment 1 - Analog elektronik. Föreläsning 4 Operationsförstärkare

DIGITALTEKNIK I. Laboration DE1. Kombinatoriska nät och kretsar

Att fånga den akustiska energin

Undersökning av logiknivåer (V I

Lathund för Bose T1 ToneMatch engine

LABORATIONSINSTRUKTION DIGITAL REGLERTEKNIK. Lab nr. 3 DIGITAL PI-REGLERING AV FÖRSTA ORDNINGENS PROCESS

TETRIS. LTH, Campus Helsingborg EITA15 Digitala System

Laborationsrapport. Kurs Elinstallation, begränsad behörighet. Lab nr 2. Laborationens namn Växelströmskretsar. Kommentarer. Utförd den.

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 12

Laboration 1 Introduktion till Visual Basic 6.0

Laborationens mål är att få displayen att visa timmar, minuter och sekunder samt att kunna ställa klockan.

Övning2 Datorteknik, HH vt12 - Programmering

Grundläggande A/D- och D/A-omvandling. 1 Inledning. 2 Digital/analog(D/A)-omvandling

Digitalteknik: CoolRunner-II CPLD Starter Kit Med kommentarer för kursen ht 2012

TDDC74 Lab 04 Muterbara strukturer, omgivningar

Pulsmätare med varningsindikatorer

Per Holm Lågnivåprogrammering 2014/15 24 / 177. int och double = = 2, 147, 483, 647

Programmering med Arduino

2 Laborationsutrustning

Analog till Digitalomvandling

Effekter och ljudprocessorer

Kapitel 2 o 3. Att skicka signaler på en länk. (Maria Kihl)

Lab 3. Några slides att repetera inför Lab 3. William Sandqvist

Analog till Digitalomvandling

Signalbehandling, förstärkare och filter F9, MF1016

Digital Signalbehandling i Audio/Video

Programmera i Block Editor

Talsystem Teori. Vad är talsystem? Av Johan Johansson

Mekanisk solros, Digitala projekt(edi021) Kristoer Nordvall, Stefan Windfeldt, Inlämmnad: 4 december 2006

I denna laboration undersöker vi hur aritmetiska beräkningar utförs. Vi tittar på olika variabeltyper: 8-bitars, 16-bitars, 32-bitars och flyttal.

Design av inbyggda system. Innehåll. Hårdvarunära design. Hårdvarunära design. Hårdvarunära design. Hårdvarunära design TDD

A/D- och D/A- omvandlare

HI1024 Programmering, grundkurs TEN

Elektronik Elektronik 2019

Programmera i teknik - kreativa projekt med Arduino

Minneselement,. Styrteknik grundkurs. Digitala kursmoment. SR-latch med logiska grindar. Funktionstabell för SR-latchen R S Q Q ?

DIGITALTEKNIK. Laboration D161. Kombinatoriska kretsar och nät

Lågnivåprogrammering. Föreläsning 2 Lågnivåprogrammering. Binära tal. En enkel modell av datorns inre

Design vid utveckling av inbyggda system

[] Arrayer = Indexerad variabel

Transkript:

Lab 5 I denna laboration ska ni testa på hårdvarunära programmering och realtidsprocessning av ljud. Till er hjälp har ni ett enkelt shield till Arduino. Ett shield är som ett skal som man trycker på Arduino för att få extra funktioner. Så här är shieldet konfigurerat: I huvudsak kommer ni att använda er av ljudingången, potentiometern i mitten mellan ingång och utgång för att justera ljudnivån på ingången och som leder ljudsignalen till analogingång 0, samt potentiometern nere till vänster som är kopplad till analogingång 1. Arduino är enkel och billig, men egentligen inte så väl lämpad för denna uppgift. Klockfrekvensen i ett Arduino är 16MHz, och den har bara 32kB i minne för program och 2kB SRAM, men för denna uppgift är den lagom utmanande och tillräcklig. I ovanstående schema ser ni kopplingarna mellan shield (dvs alla komponenter förutom Arduinot) och de olika in- och utgångarna på Arduinot. Ingångssignalen dämpas med potentionmeter R4, passerar genom DC-blockerare C1 och lyfts sedan med kopplingen kring R7 (dvs DC-offseten förändras), och går sedan till analogingång 0. Signalen måste lyftas DCmässigt eftersom Arduinot (som har enkel spänningsmatning) samplar inkommande signal

mellan 0 och +5V. Genom R7 lyfts signalens mittpunkt till +2.5V. Lägg märke till att ett lågpassfilter saknas på ingången, och fundera över vad det innebär i sammanhanget. Utgången, pulsebreddsmodulation (PWM) på digitalpin 11, passerar genom ett lågpassfilter, passerar sedan genom en kondensator C7 som flyttar signalen till att svänga runt 0V igen, och passerar sedan ett notchfilter som filterar bort rester från DA-omvandlingen. Arduinos funktioner för att läsa och skriva information från de analoga ingångarna till de digitala PWM-utgångarna är inte så bra eller i alla fall inte så snabba. Därför körs denna del av koden direkt mot Atmega32-processorn med AVR-kod genom nedanstående interruptprocess. Då denna del av laborationen är lite utanför focus för kursen är koden färdigskriven, men vill ni och kan ni så skriv gärna om och förbättra. Ert focus för laborationen är att skriva huvudprogrammet som utför själva signalbehandlingen. I interruptprocessen sätts en flagga (sampleflag) som talar om för huvudloopen att en ny sample har tagits. När denna flagga är 1, sätts den till 0 och signalbehandlingen utförs. Beroende på vilken typ av signalbehandling ni utför så sker olika saker i huvudloopen, men den slutar alltid med att ett värde skrivs till digitalutgång 11 som har PWM. Vanligtvis skulle vi använda analogwrite i Arduino, men då det är lite för långsamt använder vi OCR2A. I

huvudloopen har ni redan fått kontroll av flaggan samt loopbackfunktion av sampling till utgången. För att laborationen ska gå att genomföra skapas en SRAM-buffert dit vi kan skriva samplevärden och läsa samplevärden från. Vi använder en buffert på 512 steg (eller 512 bytes). Arduinot har sammanlagt 2kB SRAM, och detta minne ska räcka till alla variabler som används av programmet. SRAM bufferten läser vi från 0 till 511 och så runt från 0 igen. Vi lagrar ett samplevärde på varje position så det ryms 512 samplingsvärden eller knappt 0.033 sekunder ljud i bufferten. Uppgiften Ni ska med hjälp av Arduinot skapa en realtidseffekt, först en overdrive/distorsion och sedan väljer ni en av följande ljudeffekter: flanger, ringmodulator, reverb. Blir uppgiften för enkel gör ni ljudeffekten bättre och/eller smartare, eller så gör ni mer än en typ av ljudeffekt. Granska befintlig kod och kommentarer Innan ni börjar koda. Bekanta er med den befintliga koden och strukturen. Börja med de olika globala variablerna, kolla sedan framför allt på funktionen fillsrambufferwithsinus och på Timer2-interrupten (som ligger längst ned i koden). Kolla sedan in på den korta och torftiga void loop-funktionen. Egentligen behövs inte funktionen fillsrambufferwithsinus till mer än ringmodulatorn, men kanske kan ni komma på ytterligare användning av den funktionen i de övriga ljudeffekterna. Testa loopbackfunktionen När ni känner att ni har ok koll på den befintliga koden, och kanske har kollat in https://www.arduino.cc/ för att ha bättre koll på kod och struktur i Arduino, och kanske till och med kollat igenom länkarna i slutet av detta dokument, kan ni börja med att koppa ihop ett Arduino med en av de analoga småsyntarna och högtalaren. Det är lite ont om utrustning tyvärr, så samsas med de övriga är ni snälla. Den globala variabeln sampleflag är en boolean, och deklareras som en volatile. Det innebär att variabeln kan komma att ändras bortom kontrollen av koddelen där den används. I Arduino kan detta betyda att variabeln kan ändras i exempelvis en interrupt vilket är fallet här (kolla bilden ovan om interruptprocessen). Ljudet, dvs den globala variabeln badc0 som är en volatile byte, skrivs till den analoga utgången (PWM på digitalpin 11).

Om allt funkar som det ska och ni har kopplat det hela rätt ska ni höra ljudet, samplat genom Arduinot i högtalaren. Skapa en overdrive Även om det kan tyckas vara lite onödigt att göra en overdrive av en 8-bitars samplad signal med ett Arduino är det trots allt en ganska trevlig inkörsport till denna laboration. Vi kommer att använda några globala variabler, fixa DC-offset och hårdlimitera ljudet, samt skriva det bearbetade ljudet till utgången igen. Genomgående i laborationen har jag försökt att använda soundsamplefromadc som en samplecontainer för inkommande ljudsample och srambuffersamplevalue som en samplecontainer för utgående ljudsample. Det innebär dock att det blir lite krystat med dessa variabelnamn ibland. Stoppa först inkommande ljudsample i soundsamplefromadc och ta bort DC-offseten. Tänk efter var DC-offseten borde ligga om vi har samplat med 8 bitar och ingångsnivån var mellan 0 och +5V. Värdet på potentiometern stopps i variabeln badc1, kolla i Timer2-interrupten. Värdet på badc1 är ett 8-bitarsvärde. Multiplicera soundsamplefromadc med det värdet men skala om det till en fjärdedel och se till att det som lägst är 1. Om badc1 är 0 så får ni ju inte ut något ljud alls Eftersom ni har fixat DC-offseten på ljudet så att det nu har 0 i mitten kan ni hårdlimitera det för att undvika att utgången överstyr. Vi vill förvisso ha overdrive, men inte fulöverstyrning. Ljudsamplen är ett 8-bitarstal med 0 i mitten. Så, skriv två if-satser som tar ljud över och under max och sätter dem till max. Avslutningsvis ska ni lyfta upp ljudet, soundsamplefromadc, till rätt DC-offset igen och lägg det i srambuffersamplevalue, för att sedan skicka det till PWM-utgången OCR2A. med inställbar mängd overdrive/distorsion i högtalaren. Välj sedan en av följande effekter att jobba vidare med: flanger, ringmodulator, reverb. Skapa en flanger En flanger är enkel att skapa utifrån detta ganska enkla ramverk. Börja med att kommentera bort koden till overdriven, eller spara om projektet i ett nytt filnamn. Flangern är faktiskt den enda av dessa ljudeffekter där DC-offseten inte har någon betydelse, å andra sidan lär det inte förstöra effekten om ni tar hänsyn till DC-offseten heller. Kom ihåg hur en flanger fungerar. Kort uttryckt så mixas originalljudet med en fördröjd signal av densamma, och där mängden fördröjning varieras. När originalljud och fördröjt ljud summeras uppstår kamfilter effekter med fasutsläckning respektive fasförstärkning. Stoppa först inkommande ljudsample i soundsamplefromadc och skriv den till srambuffer på position bufferindex. Läs sedan position bufferindex2 från srambuffer och stoppa det samplevärdet i soundsamplefromsrambuffer. Räkna sedan upp bufferindex, och sätt bufferindex2 till bufferindex med fördröjningen enligt potentiometerns värde, badc1.

Eftersom srambuffer har 512 positioner måste vi anpassa bufferindex och bufferindex2 så att dessa inte blir för höga. Detta görs enkelt med modulo (%) för bufferindex, och med & 511 för bufferindex2. Dessa två metoder är lite olika, fundera på vad skillnaden är och varför dessa två olika sätt används. När våra index är korrekta ska de två ljudsamplen, originalsamplen och den fördröjda sampeln, summeras. Tänk på att anpassa ljudnivån så att det inte överstyr då ni summerar två samples. Därefter skickar ni det summerade ljudet, dvs srambuffersamplevalue, till utgången, som ni gjort i de tidigare övningarna ovan. med inställbar fördröjning av det buffrade ljudet i högtalaren. Det kommer att låta som ett kamfilter om ni inte vrider potentiometern fram och tillbaka och skapar den riktiga flangereffekten för hand. Fundera på hur detta skulle gå att snygga till och skapa en automatisk flangingeffekt. I stället skulle i så fall potentiometerns värde kunna användas till att ställa hur mycket effekt som ska användas, eller till att sätta frekvensen på LFOn som skapar den automatiska effekten. Skapa en ringmodulator Även ringmodulatorn är tämligen enkel att skapa utifrån detta ramverk. Börja med att kommentera bort koden från föregående övning, eller spara om projektet i ett nytt filnamn. I denna effekt behöver ni ta hänsyn till DC-offseten i 8-bitars samplevärdet. Stoppa först inkommande ljudsample i soundsamplefromadc och ta bort DC-offseten. Läs sedan sinusvågen på position bufferindex till srambuffersamplevalue och ta bort DCoffset även från den. Ringmodulation är detsamma som en multiplikation av två vågformer, dvs en frekvensmix. Multiplicera därför de två ljudsampelna med varandra. Sedan måste ni skala om till max i 8- bitars tal, och därefter lägga till DC-offseten igen. Stoppa summan i utgångsvariabeln. När de två vågformerna, eller de samplevärdena i detta fall, är multiplicerade med varandra så har vi skapat en enkel ringmodulator. Men, för att denna effekt ska bli lite mer intressant så ska potentiometerns värde sätta frekvensen för sinusvågen. Detta görs genom att förändra bufferindex genom summera bufferindex med värdet i badc1. Dock måste bufferindex öka i normalt tempo (dvs som i de övriga övningarna) med 1 även om bufferindex är inställd på 0. Detta görs väldigt enkelt med en ökning med 1 på liknande sätt som i övriga övningar, eller genom att använda map enligt: map(value, fromlow, fromhigh, tolow, tohigh). Att använda map vore kanske en bra pedagogisk övning för att testa på den funktionen, men det är tämligen onödigt krångligt i detta fall. Glöm avslutningsvis inte att begränsa räkningen av bufferindex med modulo (%) så att inte indexet överstiger antalet positioner i srambuffer. Avslutningsvis ska ni skicka det nya ljudet, dvs srambuffersamplevalue, till utgången. med inställbar frekvens av ringmodulationen. Det kommer nog inte att låta så vackert, men härligt knasigt ringmodulerat. Fundera på hur ringmodulatoreffekten kunde förbättras. Kanske kunde påverkan av sinusvågen påverkas, men hur skulle detta kunna lösas och vilken effekt på slutljudet skulle det få?

Skapa ett reverb Reverbet är nog den mest komplicerade uppgiften att skapa utifrån detta ramverk, men personligen tycker jag att det också är det mest belönande. Det är till och med så att jag har funderat på att faktiskt bygga in reverbet i en av modularsyntarna. Börja med att kommentera bort koden från föregående övning, eller spara om projektet i ett nytt filnamn. I denna effekt behöver ni ta hänsyn till DC-offseten i 8-bitars samplevärdet. Läs först position bufferindex från srambuffer och stoppa det samplevärdet i soundsamplefromsrambuffer. Ta bort DC-offseten från samplevärdet från buffern. Men gör detta och vänd samtidigt på fasen. Klura lite extra på detta steg, skillnaden mellan att bara ta bort DC-offset som vi gjort i tidigare övningar ovan och att både ta bort DC-offset och vända fasen är faktiskt väldigt liten. Sedan ska ni öka värdet på samplen från buffern genom att multiplicera det med värdet från potentiometern, badc1. Skala sedan ned värdet igen till rätt nivå för 8-bitar. Stoppa sedan inkommande ljudsample i soundsamplefromadc och ta bort DC-offseten, och summera inkommande ljudsample med det skalade värdet från buffern. Egentligen kunde vi dividera ljudet med 2 för att undvika att det överstyr, men nu vill vi faktiskt pressa upp nivån på ljudet. Gör därför en hård limitering på samma sätt som vid overdriven ovan. Därefter ska ni lägga till DC-offset igen och spara det nya samplevärdet i srambuffer på position bufferindex. Tänk nu efter hur detta reverb fungerar. Varje sample blandas med en tidigare sample och sparas sedan ned i buffern igen, så efter ett kort tag kommer den första samplen att blandas med en ny sample och sparas, och sedan kommer den blandningen att blandas med en ny sample och sparas, och runt och runt och runt. Därför kan det vara bra att sänka samplevärdet något innan den skrivs till buffern, exempelvis med samplevärde * 0.9. Därefter ska bufferindex räknas upp och begränsas med modulo (%) så att inte indexet överstiger antalet positioner i srambuffer. Avslutningsvis ska ni skicka det samplevärdet i srambuffersamplevalue till utgången. med inställbar mängd/längd av reverbet. Fundera på om reverbljudet kunde förbättras? Kanske kunde den ljudsample som läses från buffern lågpassfiltreras för ett mjukare reverbljud? Hur kunde ett större reverb kunna skapas, med längre efterklangstid? Om ni har gjort allt och ändå har tid kvar Ett delay bygger på liknande teknik som en flanger, men med längre tidsskillnad mellan originalljud och fördröjt ljud. Hur skulle det vara möjligt att skapa ett delay? Vilka utmaningar och problem skulle vi stöta på? Även ett chorus bygger på en liknande teknik som en flanger, men med en fast tidsskillnad mellan originalljud och effektljud. Det som skapar effekten i ett chorus är att effektljudet är i en annan pitch/frekvens (eller åtminstone en pitchmodulerad variant av originalljudet) vid summering med originalljud. Hur kunde denna effekt skapas? Kunde det pitchmodulerade ljudet skapas med hjälp av ringmodulation? Vilka utmaningar och problem skulle vi stöta på?

Vidare läsning Arduino https://www.arduino.cc/ Arduino, referense för den C-aktia koden https://www.arduino.cc/en/reference/homepage Arduino, IDE (programmeringsmiljön) https://www.arduino.cc/en/main/software Secrets of Arduino PWM https://www.arduino.cc/en/tutorial/secretsofarduinopwm ADC (Analog To Digital Converter) of AVR Microcontroller http://extremeelectronics.co.in/avr-tutorials/using-adc-of-avr-microcontroller/ The ADC of the AVR, Analog to Digital Conversion http://maxembedded.com/2011/06/the-adc-of-the-avr/ ATmega32, datablad http://www.atmel.com/images/doc2503.pdf Low-level ADC control: ADMUX http://openenergymonitor.blogspot.se/2012/08/low-level-adc-control-admux.html CBI - Clear Bit in I/O Register http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_cbi.html SBI - Set Bit in I/O Register http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_sbi.html