[Delphi] Hoe pieptoon opvangen?

Pagina: 1
Acties:
  • 691 views sinds 30-01-2008
  • Reageer

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Mensen,

Voor een project wat bestaat uit een stukje software (zelfgemaakt in Delphi 6) en wat hardware (zelfgemaakt met de soldeerbout >:) ) heb ik een IC nodig wat een pieptoon kan detecteren. De hardware bestaat uit een parallelepoort interface en een ingang wat op de LINE-out van de computer wordt aangesloten. Verder zitten er nog wat onderdelen op waaronder een microcontroller (denkelijk PIC18F452), maar deze zijn van minder belang. Het gaat zich om de hardware wat aan de LINE-out van de computer zit. Ik krijg op een bepaald moment namelijk van de computer wat geluiden te horen. Het is de bedoeling dat een IC (of iets anders?) een pieptoon detecteerd. Daarna moet'ie bijvoorbeeld even een puls ofzo geven aan de microcontroller.

Het geluidssignaal ziet er ongeveer zo uit:

stilte.....vrouwenstem.....stilte....PEEEP.....stilte.....(klik voor *.wav)

Mijn vraag is daarom natuurlijk: bestaan er IC's die deze piep kunnen opvangen? Of hebben jullie andere/betere ideeën om dit aan te pakken?

  • Pino
  • Registratie: Oktober 2001
  • Laatst online: 04-05 15:48
heb je invloed op de piep? Zo ja, dan zou je een DTMF demodulator kunnen gebruiken en een bepaalde DTMF toon als piep kunnen gebruiken.

"If you don't know where you are going, any road will take you there"


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
THEF_Pino schreef op vrijdag 10 juni 2005 @ 10:19:
heb je invloed op de piep? Zo ja, dan zou je een DTMF demodulator kunnen gebruiken en een bepaalde DTMF toon als piep kunnen gebruiken.
Nee, ik kan die piep niet veranderen. Anders zou ik inderdaad heel snel klaar zijn met een DTMF decoder. Helaas komt die piep van buitenaf. Ik denk dat ik iets nodig heb als een DTMF decoder, alleen dan een wat "universelere"...

  • Pino
  • Registratie: Oktober 2001
  • Laatst online: 04-05 15:48
Een andere mogelijkheid is een soort decibelmeter. Ik neem aan dat de piep harder is dan de stem. Dan meet je gewoon of je gedurende de tijd dat de piep duurt dezelfde db uitsturing hebt.

"If you don't know where you are going, any road will take you there"


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
THEF_Pino schreef op vrijdag 10 juni 2005 @ 10:33:
Een andere mogelijkheid is een soort decibelmeter. Ik neem aan dat de piep harder is dan de stem. Dan meet je gewoon of je gedurende de tijd dat de piep duurt dezelfde db uitsturing hebt.
Ja zoiets zou natuurlijk ook kunnen. Dit zou dan direct met de microcontroller kunnen... (denk ik).
Ik zou even niet weten hoe ik van een LINE signaal (uit de computer) iets kan maken wat de microcontroller ziet.

Het is misschien ook een mogelijkheid om het softwarematig te doen. Want uiteindelijk komt het daar toch op neer. Die hardware gebruik ik alleen voor die piep te ontvangen en daarna de software aan te spreken (via die LPT1 interface). Dus als het direct in de software kan is nog mooier. Maar ik denk dat dit een nog moeilijkere oplossing is...

  • Martkrui
  • Registratie: Februari 2002
  • Laatst online: 29-04 21:04
Heb je wel spec's van de piep ?
Als je de freq weet zou wat r/c filters kunnen bouwen zodat je (bijna) alleen die piep doorlaat.
Dan iets van een gelijkrichter en een schmidt trigger oid ?

I haven't lost my mind! It's backed up on tape somewhere!


  • Pino
  • Registratie: Oktober 2001
  • Laatst online: 04-05 15:48
atmoz schreef op vrijdag 10 juni 2005 @ 10:37:
[...]


Ja zoiets zou natuurlijk ook kunnen. Dit zou dan direct met de microcontroller kunnen... (denk ik).
Ik zou even niet weten hoe ik van een LINE signaal (uit de computer) iets kan maken wat de microcontroller ziet.

Het is misschien ook een mogelijkheid om het softwarematig te doen. Want uiteindelijk komt het daar toch op neer. Die hardware gebruik ik alleen voor die piep te ontvangen en daarna de software aan te spreken (via die LPT1 interface). Dus als het direct in de software kan is nog mooier. Maar ik denk dat dit een nog moeilijkere oplossing is...
Ik denk dat het softwarematig veel makkelijker op te lossen is hoor! Omweg via line out is nogal omslachtig.

Ik ben even voor je aan het zoeken geweest, ga eens op zoek naar beatdetectie. Je kunt de mixer van je soudcard uitlezen en er zijn verschillende tools om Beats per minute te lezen. Als je daar wat frequenties verandert wordt het vanzelf een Beep detectie.

[ Voor 15% gewijzigd door Pino op 10-06-2005 11:08 ]

"If you don't know where you are going, any road will take you there"


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Dr.DNA schreef op vrijdag 10 juni 2005 @ 10:46:
Heb je wel spec's van de piep ?
Als je de freq weet zou wat r/c filters kunnen bouwen zodat je (bijna) alleen die piep doorlaat.
Dan iets van een gelijkrichter en een schmidt trigger oid ?
Nee, ik heb geen verdere specs van de piep (alleen die *.wav in de startpost). Dat is precies die piep!!
bestaan er dus geen IC's die lijken op een DTMF decoder maar waar je met bijvoorbeeld andere weerstandjes de freq. kunt bepaken?
THEF_Pino schreef op vrijdag 10 juni 2005 @ 10:47:
[...]


Ik denk dat het softwarematig veel makkelijker op te lossen is hoor! Omweg via line out is nogal omslachtig.

Ik ben even voor je aan het zoeken geweest, ga eens op zoek naar beatdetectie. Je kunt de mixer van je soudcard uitlezen en er zijn verschillende tools om Beats per minute te lezen. Als je daar wat frequenties verandert wordt het vanzelf een Beep detectie.
Tja, software is zeker beter. Maar ik ben dus echt niet zo goed in Delphi dat ik de soundcard kan aanspreken enzo. Ik maar database progsels en dat soort dingen... De soundcard aanspreken (terwijl een ander programma die al in gebruik heeft) zal wel heel moeilijk zijn. Als ik de frequentie wist van de piep kan ik misschien in de microcontroller iets bouwen wat naar die freq. kijkt (ongeveer) want een vrouwenstem en een piep verschillen nogal wat in freq.

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 04-04 15:52

Sprite_tm

Semi-Chinees

Je kan het softwarematig in je PIC oplossen: fiets iets inelkaar met een comparator ofzo wat een 1 op de uitgang geeft als het line-out-signaal positief is en een 0 als het negatief is. Ga dan met de PIC de tijd meten die het duurt voordat het signaal omklapt. Als je dan de piep hebt, meet je heel vaak een tijd die ongeveer (1/(freq*2)) seconden duurt, en zo kan je PIC uitvinden of de piep aanwezig is.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


Verwijderd

Het comparator idee is volgens mij idd het minst omslachtige.Qua filtering weet ik helaas niet hoe je het moet aanpakken.
Ik zou het persoonlijk bekijken zoals een software UART, waarbij je op bepaalde tijdstippen kijkt of de ingang hoog of laag is, waarbij je natuurlijk wel eerst moet weten welke frequentie je pieptoon heeft.
Als je dit nu bv 1 sec lang doet (afhankelijk van hoe lang de pieptoon duurt) kan je uitsluiten dat de vrouwenstem frequenties aanspreekt die je signaal triggeren.
Maarreuh zoals ik zei, signaalverwerking is niet mn sterkste kant :9

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Oke bedankt allen.
Ik denk dat ik eens aan de slag ga met de microcontroller, want heb ik net een tijdje naar Delphi zitten kijken en dat lijkt me echt veel meer werk. Ik heb een soort voorbeeldprogramma gevonden wat de waveform van de microfooningang laat zien, maarja haal daar maar eens die piep uit....

  • virus.elektro
  • Registratie: Januari 2002
  • Laatst online: 08:28

virus.elektro

profesionele monitor sloper

Er bestaan speciale ic's om tonen mee te detecteren.
* virus.elektro pakt heel fout boekje uit de kast (electronica echt niet moeilijk deeltje 4)
567 is het nummer. uitgang is een open collector of emitter

elektrotechniek is leuk (nog wel). ik ga dus weer verder met leuke dingen ontwerpen. amd 2200+ 256mb 333mhz,gf4 440mx, 120gb,16X dvd. jarr-url


  • tafkaw
  • Registratie: December 2002
  • Laatst online: 05-05 21:22
Anders zou je ook kunnen kijken dat wanneer er uberhaupt geluid komt (vrouwenstem etc.) dat ie dan nog X seconden wacht en dan verder gaat met wat ie doen moet na de piep... (Gokje: Je gaat iets doen met voicemail...)

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
virus.elektro schreef op vrijdag 10 juni 2005 @ 18:59:
Er bestaan speciale ic's om tonen mee te detecteren.
* virus.elektro pakt heel fout boekje uit de kast (electronica echt niet moeilijk deeltje 4)
567 is het nummer. uitgang is een open collector of emitter
Thanks!! Hier was ik dus naar opzoek. Dit lijkt me echt de beste manier. Met wat externe componenten kun je de frequentie instellen. Hiermee ga ik aan de slag.
Gr0wLiThE schreef op vrijdag 10 juni 2005 @ 19:18:
Anders zou je ook kunnen kijken dat wanneer er uberhaupt geluid komt (vrouwenstem etc.) dat ie dan nog X seconden wacht en dan verder gaat met wat ie doen moet na de piep... (Gokje: Je gaat iets doen met voicemail...)
Nee, dat kan helaas niet. Het moet PRECIES (+/- 500ms) na de piep zijn. De ene keer komt de piep iets later of iets eerder. Dit was in eerste instantie de oplossing, maar die bleek dus niet te werken. Ik ben niet met voicemail bezig ;)

Verwijderd

PLL is idd geen slecht idee :) simpel en goedkoop.

Verwijderd

atmoz schreef op vrijdag 10 juni 2005 @ 11:38:
[...]


Als ik de frequentie wist van de piep kan ik misschien in de microcontroller iets bouwen wat naar die freq. kijkt (ongeveer) want een vrouwenstem en een piep verschillen nogal wat in freq.
ik weet niet of ik je hiermee kan helpen, maar als ik dat piepje in een audioprogramma steek en zoom op de piep geeft dit een mooie sinusgolf. ik heb ff de tijd bekeken tussen 40 periodes, 0.094 sec en als ik dat dan deel door 40 heb ik een periode van 0.00235 sec. freq van 425.5 Hz (als ik juist ben)

de grootste delen van die vrouwenstem komen op fregenties tss 151Hz en 270Hz (ongeveer hé) daar zou ik niet teveel op betrouwen want dat is geen sinusvorm meer he...

njah, heel zeker ben ik niet van wat ik schrijf hoor. (wat ik gemeten heb wel natuurlijk)
mss kan dit wat nauwkeuriger door een loopje van die peep in een occiloscoop te steken, maar dat heb ik hier niet staan.

  • Luxx
  • Registratie: Februari 2001
  • Laatst online: 05-05 23:37

Luxx

Hijs nu het zeil gezwind...

Verwijderd schreef op vrijdag 10 juni 2005 @ 22:47:de grootste delen van die vrouwenstem komen op fregenties tss 151Hz en 270Hz (ongeveer hé) daar zou ik niet teveel op betrouwen want dat is geen sinusvorm meer he...
Dat lijkt me onwaarschijnlijk, de 'gemiddelde' vrouwenstem moet je toch wel in een paar kilohertz zoeken, denk ik. een vrouw met zo'n lage gemiddelde frequentie klinkt volgens mij nogal eng:p

Overigens moet het 'redelijk' eenvoudig zijn om met software een Fourier-analyse uit te voeren, en daarmee de piep te herkennen... maar goed,als je het liever in hardware zoekt vind ik het ook prima. Succes!

HYEHEHEHEEHHEEHee, hier had iets zinnigs kunnen staan, maar dat is niet.


Verwijderd

k heb mij eerlijk gezegt nog nooit afgevraagt met welke frequentie een vrouw spreekt, maar ik heb gewoon de delen waar ik een ietwat mooie periode in kon herkenen even op frequentie nagekeken, en idd ja daartussen zitten deeltjes met een hogere frequentie maar met kleinere amplitudes.

k zeg het erbij dat ik niet weet wat de wetenschappelijke waarde ervan is of hoe de nauwkeurigheid is. t is maar om te zeggen dat het meten van die frequentie het probleem toch niet kan zijn...

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Als je het hardwarematig wilt doen zou ik het ook zoeken in de duur van die bepaalde toon. De 567 lijkt me hier zeker geschikt voor. De frequentie van die toon zal ook wel voorkomen in de stem, ik weet niet hoe gevoelig de 567 hiervoor is maar als je met een microcontroller of een simpele timer een minimumduur van die toon eist kan het bijna niet mis gaan.

Softwarematig is toch ook niet heel moeilijk volgens mij, om een specifieke toon te herkennen is het Goertzel algorithm erg handig. Deze kan de amplitude (en eventueel fase) van een bepaalde toon bepalen uit gegeven sample data. Het is in essentie een enorm eenvoudig algoritme, voor elke sample een paar simpele vermenigvuldigingen en optellingen, al zijn de meeste wiskundige notaties ervan niet even duidelijk. De duidelijkste uitleg heb ik hier gevonden: Embedded.com - The Goertzel Algorithm, en werkende C++ code hier: tone detection with Goertzel (al volgt die code niet exact het algoritme geloof ik, het werkt wel).

edit: In de comments van die laatste link staat zelfs een Delphi versie, wat wil je nog meer :)

[ Voor 5% gewijzigd door madwizard op 11-06-2005 01:35 ]

www.madwizard.org


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Verwijderd schreef op vrijdag 10 juni 2005 @ 22:47:
[...]


ik weet niet of ik je hiermee kan helpen, maar als ik dat piepje in een audioprogramma steek en zoom op de piep geeft dit een mooie sinusgolf. ik heb ff de tijd bekeken tussen 40 periodes, 0.094 sec en als ik dat dan deel door 40 heb ik een periode van 0.00235 sec. freq van 425.5 Hz (als ik juist ben)

de grootste delen van die vrouwenstem komen op fregenties tss 151Hz en 270Hz (ongeveer hé) daar zou ik niet teveel op betrouwen want dat is geen sinusvorm meer he...

njah, heel zeker ben ik niet van wat ik schrijf hoor. (wat ik gemeten heb wel natuurlijk)
mss kan dit wat nauwkeuriger door een loopje van die peep in een occiloscoop te steken, maar dat heb ik hier niet staan.
Bedankt voor het uizoeken. Het klopt inderdaad dat de frequentie rond de 425 Hz ligt. Hier kwam ik (met hulp van een vriend) ook op uit.
madwizard schreef op zaterdag 11 juni 2005 @ 01:33:
Als je het hardwarematig wilt doen zou ik het ook zoeken in de duur van die bepaalde toon. De 567 lijkt me hier zeker geschikt voor. De frequentie van die toon zal ook wel voorkomen in de stem, ik weet niet hoe gevoelig de 567 hiervoor is maar als je met een microcontroller of een simpele timer een minimumduur van die toon eist kan het bijna niet mis gaan.

Softwarematig is toch ook niet heel moeilijk volgens mij, om een specifieke toon te herkennen is het Goertzel algorithm erg handig. Deze kan de amplitude (en eventueel fase) van een bepaalde toon bepalen uit gegeven sample data. Het is in essentie een enorm eenvoudig algoritme, voor elke sample een paar simpele vermenigvuldigingen en optellingen, al zijn de meeste wiskundige notaties ervan niet even duidelijk. De duidelijkste uitleg heb ik hier gevonden: Embedded.com - The Goertzel Algorithm, en werkende C++ code hier: tone detection with Goertzel (al volgt die code niet exact het algoritme geloof ik, het werkt wel).

edit: In de comments van die laatste link staat zelfs een Delphi versie, wat wil je nog meer :)
Dat ziet er goed uit!! Zeker nu er die Delphi functie bij staat. Gelukkig had ik al een programma gevonden wat de microfooningang grafisch laat zien op het scherm (equalizer). Voor de echte programmeurs moeten deze 2 dingen samen te voegen zijn zodat je krijgt wat ik wil. Ik kom echter pas net kijken in de programmeerwereld. Een beetje hulp met het programma zou echt fantastisch zijn. Ik heb de source + executabel HIER gezet. De functie (Goertzel) heb ik al erin gezet. Ik zou alleen echt niet weten waar ik die moet aanroepen. Het gaat nu steeds wat meer richting de softwarekant, maarja als het niet lukt ga ik terug naar hardware :)

Hopelijk kan iemand mij met dat Delphi progje helpen.

  • Buzz-01
  • Registratie: Juni 2002
  • Laatst online: 09:21
Kun je niks met een ADC die in de PIC eventueel al aanwezig is? Een zuivere sinus geeft gegarandeerd een andere waarde dan de vrouwenstem!
Veel PIC's hebben al een 8 bits ADC onboard, daar kan je dan handig gebruik van maken!

Flickr


  • redguy
  • Registratie: Augustus 2000
  • Niet online

redguy

Can Cow come out to to play ?

Als je dit hardwarematig op wilt lossen dan moet je eens kijken naar de XR2211 van de firma Exar
(http://www.exar.com/produ...ProdNumber=XR2211&areaID=)

Die kan dat perfect..deze chip werd vroeger veel gebruikt in packet radio modems die uit audio signalen met veel ruis en troep de 2 toontjes van packet radio moesten filteren.

IP Rocks


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Die goertzel werkt echt perfect zo te zien. Ik ben laatst toevallig met iets soortgelijks bezig geweest, heb toen een C# testprogje gemaakt om data door goertzel heen te halen, dit is de output op jouw geluidje:
Afbeeldingslocatie: http://www.madwizard.org/temp/goertzel.png
De lijn links is niet helemaal 0 maar in verhouding met de piek bij die toon zo veel kleiner dat het tot 0 vervalt in de grafiek. Deze output komt door steeds per 0.1 seconde van je sample het kwadraat van de goertzel magnitude te bepalen (de 'snelle methode' van die eerste link die ik gaf). Dit is in C# geschreven, de functie is:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Goertzel algorithm
// x          data samples, range -1.0 to 1.0
// index      index in x to start processing
// N          number of samples to process
// frequency  frequency to look for
// sampleRate sample rate of the data.
// Returns the squared magnitude
float goertzel(float[] x, int index, int N, float frequency, int samplerate) 
{
    // Constants
    float k = (0.5f + (float) N * (float)frequency / (float)samplerate);
    float w = (float)((2.0f * Math.PI / N)  * k);
    float c = (float)Math.Cos(w);
    float s = (float)Math.Sin(w);
    float coeff = 2.0f * c;

    // Processing loop
    float q0 = 0.0f, q1 = 0.0f, q2 = 0.0f;
    for (int i=index;i<(index + N); i++)
    {
        float sample = x[i];
        q0 = coeff * q1 - q2 + sample;
        q2 = q1;
        q1 = q0;
    }

    // Quick magnitude calculation
    float magnitude = q1 * q1 + q2 * q2 - q1 * q2 * coeff;

    return magnitude;
}


Om het te verwerken knip je dus gewoon je data in stukjes van 0.1 seconde (48000/10 samples), die geef je aan het algoritme mee, en je krijgt de squared magnitude van de gegeven frequentie in dat stukje sample op.

www.madwizard.org


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 04-04 15:52

Sprite_tm

Semi-Chinees

Mja, dit gaat meer en meer de P&W kant op, dus ik schop 'm daar maar heen. Meteen een nickchange'tje: [EL] Hoe pieptoon opvangen? (welk IC?)->[Delphi] Hoe pieptoon opvangen?

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • douweh
  • Registratie: Maart 2001
  • Laatst online: 09-10-2024
Waardoor wordt het geluid eigenlijk gegenereerd?
is het inderdaad een wavje? Of wordt het softwarematig gegenereerd, en komt het naar buiten via de soundcard?

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Sprite_tm schreef op zaterdag 11 juni 2005 @ 14:53:
Mja, dit gaat meer en meer de P&W kant op, dus ik schop 'm daar maar heen. Meteen een nickchange'tje: [EL] Hoe pieptoon opvangen? (welk IC?)->[Delphi] Hoe pieptoon opvangen?
Bedankt ;)
douweh schreef op zaterdag 11 juni 2005 @ 15:16:
Waardoor wordt het geluid eigenlijk gegenereerd?
is het inderdaad een wavje? Of wordt het softwarematig gegenereerd, en komt het naar buiten via de soundcard?
Het geluid komt uit een programma (Skype). Het wordt dus softwarematig gemaakt en gaat via de soundkaart naar de speakers. Ik heb dus nu een kabeltje lopen van de uitgang naar de ingang van de soundkaart. Zo kan ik met dat programma wat ik eerder poste het signaal zien.

Madwizard, ik heb jou geprobeerd te mailen, maar ik kreeg:

Technical details of permanent failure:
PERM_FAILURE: SMTP Error (state 10): 550 Requested action not taken: mailbox unavailable

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Basje2001 schreef op zaterdag 11 juni 2005 @ 09:30:
Kun je niks met een ADC die in de PIC eventueel al aanwezig is? Een zuivere sinus geeft gegarandeerd een andere waarde dan de vrouwenstem!
Nee. Een ADC levert een signaal, geen waarde. Het staat natuurlijk als een paal boven water dat het die sinus een ander signaal is, maar hoe herken je dan het digitale signaal?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Buzz-01
  • Registratie: Juni 2002
  • Laatst online: 09:21
MSalters schreef op zaterdag 11 juni 2005 @ 19:20:
[...]

Nee. Een ADC levert een signaal, geen waarde. Het staat natuurlijk als een paal boven water dat het die sinus een ander signaal is, maar hoe herken je dan het digitale signaal?
Een ADC (Analoog naar Digitaal Converter) zet toch een analoog signaal (hier: geluid) om in een digitale waarde? Of bedoelen wij allebei iets anders?
Mijn idee is namelijk dat een sinus door de ADC een bepaald exact bitpatroon zal genereren wat een gewone stem niet zal doen, niet gedurende bijvoorbeeld een halve seconde. Als je de PIC laat triggeren op dit bitpatroon, kijkt of dit een x aantal milliseconden lang aanwezig is, dan weet je redelijk zeker of het specifieke geluidje voorbijgekomen is. Heb het zelf nooit zo geprobeerd, is puur theoretisch gebral! ;)
Maar het zou moeten kunnen werken...

Flickr


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Als ik het hardwarematig ga oplossen was ik aan het denken aan dit systeem:

Ik maak iets wat een 1 (5 volt ofzo) maakt als er geluidsignaal is (de top van een sinus). Als er geen geluid is moet er een 0 (0 volt) uitkomen. Dan laat ik de PIC in bijvoorbeeld een halve seconde kijken hoevaak er een 1 langskomt. Dit zou dan (als het signaal 425 Hz is) 212 keer voorkomen. Dus ik laat een teller oplopen iedere keer als er een 1 komt. Dus a := a + 1. Op het einde van die halve seconde meten moet a dan 212 zijn. Als dat zo is is het die pieptoon. Ik weet niet of dat zo werkt, maar dat was mijn idee. Softwarematig is natuurlijk veel netter omdat ik dan helemaal geen hardware hoe te maken...

  • Buzz-01
  • Registratie: Juni 2002
  • Laatst online: 09:21
Helaas kan ik je niet verder helpen dan met wat ik al gepost heb, maar misschien is het iets om je eens verder in te verdiepen; als je met een ADC werkt, ben je waarschijnlijk nauwkeuriger dan wanneer je enkel dat signaal controleert of hij een bepaald aantal keren voor komt. Je detecteert dan namelijk ook of je enkel een zuivere sinus hebt, of een samenstelling van signalen (DTMF of spraak bijvoorbeeld), waardoor de hardwarematige oplossing die je omschrijft misschien "vals alarm" zal genereren. Je zou eens kunnen proberen wat voor waarde het oplevert als je het geluid aanbiedt op de ADC van de PIC, en of je er iets mee kunt. Je kunt het opvangen en vervolgens uitsturen op de UART naar bijvoorbeeld Hyperterminal om de waarde te bekijken. Een ADC geeft bij een sinus namelijk een andere waarde af dan wanneer je een gemengd singnaal aanbiedt. Als je wat verschillende geluiden aanbiedt, dan weet je zo of het een betrouwbare methode is, en of je er iets mee kunt!

Flickr


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Basje2001 schreef op zaterdag 11 juni 2005 @ 22:07:
[...]
Een ADC (Analoog naar Digitaal Converter) zet toch een analoog signaal (hier: geluid) om in een digitale waarde? Of bedoelen wij allebei iets anders?
Nee, dat doet een ADC niet - in elk geval niet zoals je een ADC hier gebruikt. Een digitale waarde is bijvoorbeeld 255. Zeg maar welke frequentie dat is.
In werkelijkheid genereer je een verzameling waardes met constante tijdsintervallen ertussen. Dat is dus een signaal.
Mijn idee is namelijk dat een sinus door de ADC een bepaald exact bitpatroon zal genereren wat een gewone stem niet zal doen, niet gedurende bijvoorbeeld een halve seconde. Als je de PIC laat triggeren op dit bitpatroon, kijkt of dit een x aantal milliseconden lang aanwezig is, dan weet je redelijk zeker of het specifieke geluidje voorbijgekomen is. Heb het zelf nooit zo geprobeerd, is puur theoretisch gebral! ;)
't Is inderdaad gebral. Je signaal is namelijk een sinus, met tenminste twee onbekende parameters:
V(t) = A sin (2 * π * f * t + φ0 )

De frequentie f is waarschijnlijk wel bekend, maar de amplitude A en fase φ0 niet - en die zijn analoog, dus kunnen oneindig veel waarden hebben. Daarnaast heb je nog een ruis die waarschijnlijk een paar bits verpest. Kortom, een bitpattern zoeken is volledig kansloos.

* MSalters heeft zoiets wel geprobeerd op practicum, iets moeilijker (gesproken klinkers onderscheiden)

[ Voor 8% gewijzigd door MSalters op 12-06-2005 22:30 . Reden: nette symbolen ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Als ik het zou moeten doen zou ik het zeker in software doen, gezien alles toch al software is met uitzondering van het kabeltje (misschien dat je daar ook nog een nettere oplossing voor hebt, sommige geluidskaarten hebben ook een kanaal waar je spelend geluid mee kunt opnemen ('what u hear' bij mijn SB)). Die goertzel werkt zoals ik al zei echt prima hiervoor, maar ik begrijp dat je gewoon niet genoeg programmeerkennis hebt om dit softwarematig te maken?

www.madwizard.org


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
madwizard schreef op zondag 12 juni 2005 @ 23:52:
Als ik het zou moeten doen zou ik het zeker in software doen, gezien alles toch al software is met uitzondering van het kabeltje (misschien dat je daar ook nog een nettere oplossing voor hebt, sommige geluidskaarten hebben ook een kanaal waar je spelend geluid mee kunt opnemen ('what u hear' bij mijn SB)). Die goertzel werkt zoals ik al zei echt prima hiervoor, maar ik begrijp dat je gewoon niet genoeg programmeerkennis hebt om dit softwarematig te maken?
Ja, klopt. Daarom heb ik jou een mailtje gestuurd.
Wellicht dat jij me verder kan helpen hiermee. Als ik het hardwarematig ga oplossen staat in dit topic perfecte info ervoor. Bedankt daarvoor mensen. Maar inderdaad is het een omweg om het via hardware te doen ;) (maarja in eerste instantie dacht ik dat dat de enigste oplossing was).

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
madwizard heeft me een SUPER programmatje gemaakt _/-\o_ Hiermee is het helemaal gelukt. Het is dus uiteindelijk tot een mooie software oplossing gekomen. Eigenlijk precies zoals het hoort ;)

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 04-05 13:09
Show us the source :9

[ Voor 5% gewijzigd door riezebosch op 18-06-2005 12:58 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Tis in C++ omdat dat wat makkelijker met de multimedia API werkt. Code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include <fstream>
#include <vector>
#include <cmath>
#include <string>

using namespace std;

const int SAMPLE_FREQ = 44100;
const int DETECT_SIZE = SAMPLE_FREQ / 10;

HANDLE g_event;

float g_freq;
int g_threshold;
int g_duration;

enum Mode
{
    Detect,
    Test
};

class BeepException
{
public:
    BeepException(std::string msg)
    {
        _msg = msg;
    }
    std::string what()
    {
        return _msg;
    }
private:
    std::string _msg;
};

Mode g_mode;

int g_detectCount = 0;
std::vector<float> g_arrDetect(DETECT_SIZE);

// Goertzel algorithm 
// samples    data samples, range -1.0 to 1.0 
// N          number of samples to process 
// frequency  frequency to look for 
// sampleRate sample rate of the data. 
// Returns the squared magnitude 
float goertzel(const std::vector<float> &samples, int N, float frequency, int samplerate)  
{ 
    float const PI = 3.141592654f;

    // Constants 
    float k = (0.5f + N * frequency / samplerate); 
    float w = (2.0f * PI / N)  * k; 
    float c = std::cos(w); 
    float s = std::sin(w); 
    float coeff = 2.0f * c; 

    // Processing loop 
    float q0 = 0.0f, q1 = 0.0f, q2 = 0.0f; 
    for (int i=0;i<N; i++) 
    { 
        float sample = samples[i]; 
        q0 = coeff * q1 - q2 + sample; 
        q2 = q1; 
        q1 = q0; 
    } 

    // Quick magnitude calculation 
    float magnitude = q1 * q1 + q2 * q2 - q1 * q2 * coeff; 

    return magnitude; 
}

void processPiece()
{

    float s = goertzel(g_arrDetect, DETECT_SIZE, g_freq, SAMPLE_FREQ);
    s = std::log(s);
    
    if (g_mode == Test)
    {
        for (int i=0;i<(int)s;i++)
        {
            cout << '*';
        }
        cout << endl;
        cout.flush();
    }
    else if (g_mode == Detect)
    {
        if (s > g_threshold)
        {
            g_detectCount++;
        }
        else
        {
            if (g_detectCount>g_duration)
            {
                PulseEvent(g_event);
                cout << "Beep!" << endl;
            }
            g_detectCount = 0;
        }
    }
    g_arrDetect.clear();
}


void CALLBACK waveProc(
  HWAVEIN hwi,       
  UINT uMsg,         
  DWORD dwInstance,  
  DWORD dwParam1,    
  DWORD dwParam2     
)
{
    if (uMsg==WIM_DATA)
    {
        WAVEHDR *pHeader = reinterpret_cast<WAVEHDR*>(dwParam1);
        
        if (waveInUnprepareHeader(hwi, pHeader, sizeof(WAVEHDR))!=MMSYSERR_NOERROR)
        {
            cerr << "Unprepare header failed." << endl;
            exit(1);
        }
        if (waveInPrepareHeader(hwi, pHeader, sizeof(WAVEHDR))!=MMSYSERR_NOERROR)
        {
            cerr << "Prepare header failed." << endl;
            exit(1);
        }
        if (waveInAddBuffer(hwi, pHeader, sizeof(WAVEHDR))!=MMSYSERR_NOERROR)
        {
            cerr << "Add buffer failed." << endl;
            exit(1);
        }
        short *pData = reinterpret_cast<short*>(pHeader->lpData);
        for (unsigned int i=0;i<(pHeader->dwBytesRecorded/2);i++)
        {
            g_arrDetect.push_back(pData[i]/32768.0f);   
            if (g_arrDetect.size() >= DETECT_SIZE)
            {
                processPiece();
            }
            
        }
    }
}

void showSyntax()
{
    cerr << "Syntax:" << endl 
             << endl
             << " BeepDetect list" << endl
             << "   Displays a list of devices." << endl 
             << endl
             << " BeepDetect detect {device} {frequency} {threshold} {duration}" << endl
             << "   Detects beeps. " << endl
             << "      Device: device ID, see list command for a list of devices." << endl 
             << "      Frequency: frequency to detect." << endl
             << "      Threshold: volume treshold (log2 of squared magnitude). " << endl
             << "      Duration: Minimum number of 1/20 sec parts to match a beep. " << endl
             << endl
             << " BeepDetect test {device} {frequency}." << endl
             << "   Shows the detected magnitude of the given magnitude." << endl
             << "      Device: device ID, see list command for a list of devices." << endl 
             << "      Frequency: frequency to detect." << endl
             << endl;
}
void listDevices()
{
    UINT numDevices = waveInGetNumDevs();
    for (UINT i=0;i<numDevices;i++)
    {
        WAVEINCAPS wic;
        waveInGetDevCaps(i, &wic, sizeof(wic));
        cout << "Device ID " << i << endl 
                << " " << wic.szPname << endl;
    }
}

void addBuffer(HWAVEIN waveIn)
{   
    WAVEHDR *pHeader = new WAVEHDR;
    pHeader->dwBufferLength = DETECT_SIZE * 2;
    pHeader->lpData = new char[pHeader->dwBufferLength];
    pHeader->dwFlags = 0;
    
    if (waveInPrepareHeader(waveIn, pHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
        throw BeepException("Prepare header failed.");
    if (waveInAddBuffer(waveIn, pHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
        throw BeepException("Add buffer failed.");
}

int main(int argc, char* argv[])
{
    UINT devID = 0;

    if (argc < 2)
    {
        showSyntax();
        return 1;
    }
    char *pCommand = argv[1];
    if (strcmpi(pCommand, "list")==0)
    {
        listDevices();
        return 0;
    }
    else if (strcmpi(pCommand, "detect")==0)
    {
        if (argc!=6)
        {
            cerr << "Invalid syntax." << endl;
            showSyntax();
            return 1;
        }
        devID = atoi(argv[2]);
        g_freq = static_cast<float>(atoi(argv[3]));
        g_threshold = atoi(argv[4]);
        g_duration = atoi(argv[5]);
        g_mode = Detect;
    }
    else if (strcmpi(pCommand, "test")==0)
    {
        if (argc!=4)
        {
            cerr << "Invalid syntax." << endl;
            showSyntax();
            return 1;
        }
        devID = atoi(argv[2]);
        g_freq = atoi(argv[3]);
        g_mode = Test;
    }
    else
    {
        cerr << "Invalid command." << endl;
        showSyntax();
        return 1;
    }

    try
    {
        g_event = CreateEvent(NULL, FALSE, FALSE, "AtmozBeepDetect");
        if (g_event==NULL)
            throw BeepException("CreateEvent failed");

        HWAVEIN waveIn;
        WAVEFORMATEX wfe;
        wfe.cbSize = sizeof(wfe);
        wfe.wFormatTag = WAVE_FORMAT_PCM;
        wfe.nChannels = 1;
        wfe.nSamplesPerSec = SAMPLE_FREQ;
        wfe.wBitsPerSample = 16;
        wfe.nBlockAlign = wfe.nChannels * (wfe.wBitsPerSample / 8);
        wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    
        
        MMRESULT res;
        res = waveInOpen(&waveIn, devID, &wfe, reinterpret_cast<DWORD_PTR>(&waveProc), NULL, WAVE_MAPPED|CALLBACK_FUNCTION); 
        if (res != MMSYSERR_NOERROR)
        {
            throw BeepException("waveInOpen failed");
            return 1;
        }
        
        for (int i=0;i<4;i++)
            addBuffer(waveIn);

        res = waveInStart(waveIn);
        if (res != MMSYSERR_NOERROR)
        {
            throw BeepException("waveInOpen failed");
            return 1;
        }
    
        Sleep(INFINITE);
        return 0;
    }
    catch(BeepException e)
    {
        cerr << "Error: " << e.what() << endl;
        return 1;
    }
}


Linken met winmm.lib, binary: BeepDetect.exe

En nog een stukje uitleg uit een mail naar atmoz over het programma en interfacing met delphi:
Het is een console applicatie met drie commando's: list, detect en test. Doe eerst 'BeepDetect list'. Je ziet dan de input devices waar je het geluid vandaan kunt halen. Dat kan er gewoon 1 zijn maar ik heb er bijvoorbeeld 2. Het ID staat boven elk device, onthoud het ID van het device dat je wilt gebruiken.

Nu kun je met test het programma een zeer eenvoudige tekst-grafiek laten maken van de sterkte van een bepaalde frequentie in het geluid dat ie opneemt. Dus doe 'BeepDetect test 0 425' (die 0 is het device ID, kan dus ook anders zijn). Je ziet dan allemaal sterretjes voorbij komen. Het aantal sterretjes is steeds log2(magnitude) van een 0.05s geluid-stukje. Speel nu de piep af, je zult dan zoiets zien:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*
******
******
****
***
****
******


**********
************
************
************
************
************
************
************

Die laatste serie sterretjes is duidelijk de piep. Als laatste kun je nu met het detect commando de piep herkennen, daarbij moet je opgeven hoeveel sterretjes er minimaal in een piep zitten (het aantal sterretjes per regel zeg maar), en hoeveel van die er minimaal achter elkaar moeten komen (aantal rijen). De eerste is de threshold, de tweede de duration. In mijn geval hier ongeveer respectievelijk 10 en 7, neem het een beetje veilig dus 10 en 5 is beter. Bij mij dus: 'BeepDetect detect 0 425 10 5'

Als je nu de piep afspeelt zul je zo snel mogelijk nadat de piep *afgelopen* is 'beep!' op het scherm zien, en wordt een event object getriggered. Afsluiten van het programma moet steeds met Ctrl+C.

Een overzicht van de commando's zie je door alleen 'BeepDetect' te starten.

Als je je delphi programma wilt laten reageren, moet je de OpenEvent en bijvoorbeeld WaitForSingleObject API functies gebruiken. Ik weet niet precies hoe dat in Delphi gaat maar het moet niet moeilijk zijn. In C(++) kun je bijvoorbeeld zoiets doen:

C++:
1
2
3
4
5
6
7
8
9
HANDLE event = OpenEvent(EVENT_ALL_ACCESS, FALSE, "AtmozBeepDetect");
if (event == NULL)
  fout afhandelen;
while(true)
{
    if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0)
        fout afhandelen;
    // Als je hier komt is er een piep geweest.
}


AtmozBeepDetect is de naam van het event en moet per se die string zijn.
Sorry voor de lange post :P.

[ Voor 9% gewijzigd door madwizard op 18-06-2005 15:27 ]

www.madwizard.org


  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 19-04 08:22

Atmoz

Techno!!

Topicstarter
Haha, nu moet iedereeen "AtmozBeepDetect" gaan gebruiken _/-\o_

Maarja, dat mag ook wel, ik heb er immers ook (vrijwillig) voor betaald 8)

Nogmaals thanks madwizard!!

[edit]
Tenzij je natuurlijk zelf de source veranderd B) :D

[ Voor 18% gewijzigd door Atmoz op 18-06-2005 15:48 ]


  • TheBlasphemer
  • Registratie: September 2004
  • Laatst online: 13-11-2025
Offtopic:
Kwam dit tegen toen ik wat anders zocht, en het is misschien leukn om te vermelden dat je dit ook voor hele andere dingen kan gebruiken...
Als je na de "Beep!" dit in de code gooit:
code:
1
2
3
                HWND hwndWinamp = FindWindow("Winamp v1.x",NULL);
                if (hwndWinamp)
                    SendMessage(hwndWinamp,WM_COMMAND,40046,0);


kun je met:
BeepDetect detect 0 1680 6 2
winamp op pause en unpause zetten met fluiten ;)

Ik ben op dit moment mezelf proberen aan te leren om op een andere frequentie te fluiten ;)

[img=http://www.web2messenger.com/smallstatus/w2m/theblasp.png]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 05-05 22:23
MSalters schreef op zondag 12 juni 2005 @ 22:27:
Nee, dat doet een ADC niet - in elk geval niet zoals je een ADC hier gebruikt. Een digitale waarde is bijvoorbeeld 255. Zeg maar welke frequentie dat is.
Met je ADC meet je amplitude van je analoge signaal. Je weet tijd ( mbv je sample interval ) en daaruit kun je frequenties halen ( FFT bijvoorbeeld )

Of begrijp ik je verhaal nu helemaal niet?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1