DEUTSCHE VERSION |
|
Links | | | Forums | | | Comments | | | Report news |
Chat | | | Polls | | | Newsticker | | | Archive |
amiga-news.de Forum > Programmierung > Tonerkennung | [ - Search - New posts - Register - Login - ] |
First 4 5 6 7 8 -9- 10 11 | [ - Post reply - ] |
2006-09-17, 22:26 h whose Posts: 2156 User |
Zitat: Ja, man sollte das printf() danach weglassen, das stimmt eigentlich. Und GetSysTime() vor ReadEClock einsetzen. Das Programm war, wie schon erwähnt, auf die Schnelle gestrickt. Zitat: Ich vermute letzteres. Übrigens kommt der Fall "weniger Zeit" weit seltener vor als "mehr Zeit". Zitat: Ja, das hätte ich etwas "geschickter" lösen sollen... andererseits reichts für erste Tests. Es ging ja mehr darum zu zeigen, daß das timer.device in gewissen Grenzen für solche Aufgaben brauchbar ist. Zitat: Aah... sorry, das ist ein Test-Überbleibsel (habe ich heute Nacht vergessen rauszunehmen). Ich hatte da mit zwei IORequests experimentiert. Wird ersatzlos gestrichen Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ Dieser Beitrag wurde von whose am 17.09.2006 um 22:46 Uhr geändert. ] [ - Answer - Quote - Direct link - ] |
2006-09-18, 14:21 h Holger Posts: 8116 User |
Zitat: Na auf Assembler/Maschinensprachebene gibt es natürlich die elegante Möglichkeit, einfach zu addieren und wenn das Overflow-Flag gesetzt ist, das Hi-word zu inkrementieren. Bzw. eine zweite Addition mittels ADDX, was man sowieso machen müsste, wenn beide Operanden 64Bit sind, in diesem speziellen Fall wäre das allerdings eine Addition mit 0. Falls man nicht eh auf 64Bit-Befehle zurückgreifen kann. In C ist die eleganteste Möglichkeit natürlich die, dass man gleich 64Bit-Integer benutzt. Da es aber in den Amiga-Includes keine Definition dafür gibt, bleibt nur der C99-Standard, wenn man will, dass die 64 Bit-Zahlen auch compiler-übergreifend funktionieren. Mit vbcc funktionierts jedenfalls, damit habe ich mein Programm ja getestet. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2006-09-18, 18:14 h MaikG Posts: 5172 User |
>Da es aber in den Amiga-Includes keine Definition dafür gibt, >bleibt nur der C99-Standard, wenn man will, dass die 64 Bit-Zahlen >auch compiler-übergreifend funktionieren. 64 Bit geht aber unter Maxonbasic bestimmt nicht? Ich wollte das mit dem ReadEclock ja auch mal versuchen aber da gehts ja auch wieder los mit irgendwelchen overflows auf Minus testen etc. [ - Answer - Quote - Direct link - ] |
2006-09-18, 20:25 h whose Posts: 2156 User |
@MaikG: Also, es würde mich wundern, wenn MB 64Bit-Integer kennen würde. Der Test in meinem Programm funktioniert aber auch damit und ist ziemlich simpel gehalten. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-18, 23:10 h MaikG Posts: 5172 User |
>Also, es würde mich wundern, wenn MB 64Bit-Integer kennen würde. >Der Test in meinem Programm funktioniert aber auch damit und ist >ziemlich simpel gehalten. Ja, den hab ich mir ausgedruckt. Aber im Kommentar steht was mit Überläufe und man müsste auf Minus testen... Wenn das so noch kein 100%iges Programm ist fang ich lieber erst gar nicht an es in Basic umzusetzen... [ - Answer - Quote - Direct link - ] |
2006-09-18, 23:31 h Holger Posts: 8116 User |
Zitat: Du meinst wohl C code:Das funktioniert so auch in Basic.if( ((eclockval.ev_lo) + diff) < eclockval.ev_lo) { eclockval.ev_hi++; } else { eclockval.ev_lo += diff; } Das versagt erst <über den Daumen peil>ab ca. einer Stunde Wartezeit</über den Daumen peil>. Allerdings fällt mir hier gerade ein Fehler auf. Das Ergebnis der Addition muss in jedem Fall in's Low-Word geschrieben werden... Also korrekt eher so: C code:ULONG newLow = eclockval.ev_lo + diff; if(newLow < eclockval.ev_lo) { eclockval.ev_hi++; } eclockval.ev_lo = newLow; mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2006-09-19, 00:03 h whose Posts: 2156 User |
Zitat: Upps... ich habs irgendwie geahnt, daß ich da noch einen Bock drin habe... ich bin nur nicht drauf gekommen, was das sein könnte. Wald und Bäume und so... Danke für die Korrektur. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-19, 00:08 h whose Posts: 2156 User |
Zitat: Ach was, halb so wild. Auf Minus müßte man streng betrachtet testen, weil die Methode, die ich da gewählt habe, nicht immer funktioniert, eben wegen dem Vorzeichen. Daher die "Warnung" mit dem Minus. Das habe ich bei dem "Trick" außer acht gelassen (weil in diesem sehr speziellen Fall nicht zwingend notwendig) und es funktioniert für Deine Zwecke. Dem möglichen Überlauf mußt Du Rechnung tragen, weil das Programm sonst ab einer bestimmten Zeit (2^32 µs)nach Start des Rechners Unsinn liefern würde. Entweder, Du rennst im Laufe der Zeit da rein oder Du startest das Programm zufällig zur falschen Zeit, und da wärs ja doof, wenn das Programm dann Mist baut, weil wir den Überlauf von ev_lo nicht beachtet haben. Für ne Alarmanlage wärs ohne Überlauf-Test also nicht unbedingt brauchbar. Du kannst es ruhig einsetzen, weil die entsprechenden Voraussetzungen mit 99%iger Wahrscheinlichkeit erfüllt sind. Ich nehme ja nicht an, daß Du versuchst, mit gebrochenen Frequenzen beim Samplen oder allgemein mit Zeiträumen von mehr als knapp ner Stunde für DTMF-Erkennung zu arbeiten. Oder das auf andere Plattformen als AmigaOS 68K zu portieren. Bei ganzen, positiven Zahlen für die Frequenz funktioniert das. Sofern Du die von Holger korrigierte Form verwendest Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ Dieser Beitrag wurde von whose am 19.09.2006 um 00:22 Uhr geändert. ] [ - Answer - Quote - Direct link - ] |
2006-09-19, 09:54 h MaikG Posts: 5172 User |
>Ach was, halb so wild. Auf Minus müßte man streng betrachtet >testen, weil die Methode, die ich da gewählt habe, nicht immer >funktioniert, eben wegen dem Vorzeichen. Na, bei der DTMF erkennung musste sie aber immer funktionieren. >Dem möglichen Überlauf mußt Du Rechnung tragen, weil das Programm >sonst ab einer bestimmten Zeit (2^32 µs)nach Start des Rechners >Unsinn liefern würde. Entweder, Du rennst im Laufe der Zeit da >rein oder Du startest das Programm zufällig zur falschen Zeit, >und da wärs ja doof, wenn das Programm dann Mist baut, weil wir >den Überlauf von ev_lo nicht beachtet haben. Für ne Alarmanlage >wärs ohne Überlauf-Test also nicht unbedingt brauchbar. Wie hoch geht die Zahl bis der Überlauf kommt? >Ich nehme ja nicht an, daß Du versuchst, mit gebrochenen >Frequenzen beim Samplen oder allgemein mit Zeiträumen von mehr >als knapp ner Stunde für DTMF-Erkennung zu arbeiten. Eigentlich nicht so lang. [ - Answer - Quote - Direct link - ] |
2006-09-19, 12:51 h whose Posts: 2156 User |
Zitat: Sagen wir: Bei der Bemessung des Zeitraums für das Sampling und der DTMF-Erkennung funktioniert es immer. Bei anderen Aufgaben (also was anderem, als Du vorhast) könnte es, je nach Größe der verwendeten Zahlen, Probleme geben. Zitat: 2 hoch 32 = 4294967296 Je nach EClock-Rate des Rechners können da soundsoviel Minuten drin gespeichert werden. Kannst Du Dir ausrechnen, wenn Du Dir die "ticks" ausgeben läßt (Rückgabewert von ReadEClock()). Die "ticks" werden pro Sekunde angegeben. Angenommen, Dein Rechner arbeitet mit 709379 ticks/s, ergibt das 6054 Sekunden. 6054 Sekunden / 60 = 100 Minuten. Nach 100 Minuten ab Start des Rechners käme es also zu einem Überlauf von ev_lo. Würden wir den nicht berücksichtigen und mit dem "alten" Wert von ev_hi weiter arbeiten, würde das Programm ab dann mit voller Rechnergeschwindigkeit weiterlaufen, statt 125µs zu warten (weil wir einen Zeitpunkt angeben, der bereits vorbei ist). Käme also Mist bei raus. Da wir hier aber den Überlauf berücksichtigen und ev_hi brav um 1 erhöhen, passiert das nicht. Zitat: Meine ich doch. Mit dem Zeitraum ist auch der Zeitraum gemeint, der die Wartezeit ausmacht (also hier die 125µs, im Programm diff). Bei der Berechnung von diff könnte es bei zu großen Zeiträumen Schwierigkeiten geben, aber bei 125µs (oder, wie Holger schon sagte, Zeiträumen von weniger als über den Daumen gepeilt knapp einer Stunde) passiert das nicht. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-19, 20:06 h MaikG Posts: 5172 User |
Stürzt nur ab:code:eclockval&=AllocMem&(EClockVal_sizeof%,MEMF_CLEAR&) ticks&= ReadEClock&(eclockval&) Intervall%=8000 diff&=ticks&/Intervall% IF PEEKL(eclockval&+ev_lo%)+diff& < PEEKL(eclockval&+ev_lo%) THEN POKEL(eclockval&+ev_hi%),PEEKL(eclockval&+ev_hi%)+1 ELSE POKEL(eclockval&+ev_lo%),PEEKL(eclockval&+ev_lo%)+diff& END IF POKEW tr& + tr_node% + IORequestio_Command%, TR_ADDREQUEST& POKEL tr& + tr_time% + tv_secs%, PEEKL(eclockval&+ev_hi%) POKEL tr& + tr_time% + tv_micro%, PEEKL(eclockval&+ev_lo%) SendIO&(tr&) t!=TIMER WHILE Repeat1%<Intervall% junk&=WaitPort&(timerport&) WHILE TimerMsg&=GetMsg&(timerport&) WEND newLow&=PEEKL(eclockval&+ev_lo%)+diff& IF newLow&<PEEKL(eclockval&+ev_lo%) THEN POKEL(eclockval&+ev_hi%),PEEKL(eclockval&+ev_hi%)+1 POKEL(eclockval&+ev_lo%),newLow& POKEW tr& + tr_node% + IORequestio_Command%, TR_ADDREQUEST& POKEL tr& + tr_time% + tv_secs%, PEEKL(eclockval&+ev_hi%) POKEL tr& + tr_time% + tv_micro%, PEEKL(eclockval&+ev_lo%) SendIO&(tr&) INCR repeat1% INCR mycount%:IF mycount%=8000 THEN mycount%=0:INCR myseconds% REM :move rpS&,20,25:Text rpS&, SADD(TIME$+CHR$(0)),8 sa&=PEEKB(&hBFE101)<<8 IF sa&>&H7FFF THEN sa&=sa& OR &HFFFF0000& bla%=goertzel%(sa&) WEND move rpS&,20,45:Text rpS&, SADD(STR$(TIMER-t!)+CHR$(0)),LEN(STR$(TIMER-t!)) move rpS&,20,55:Text rpS&, SADD(STR$(myseconds%)+CHR$(0)),LEN(STR$(myseconds%)) AbortIO&(tr&) junk&=WaitIO&(tr&) FreeMem eclockval&,EClockVal_sizeof% [ Dieser Beitrag wurde von MaikG am 19.09.2006 um 20:06 Uhr geändert. ] [ Dieser Beitrag wurde von MaikG am 19.09.2006 um 20:07 Uhr geändert. ] [ - Answer - Quote - Direct link - ] |
2006-09-19, 22:05 h Ralf27 Posts: 2779 User |
Ich hab jetzt nicht denn ganzen Thread gelesen, aber folgene Zeile hat mich eben etwas überrascht:code:eclockval&=AllocMem&(EClockVal_sizeof%,MEMF_CLEAR&) Reicht es aus einfach MEMF_CLEAR& anzugeben, wenn man einen beliebigen Speicherbereich benötigt? Bzw. wird dann immer Fast bevorzugt? Oder muß man da doch noch angeben was man will? -- http://www.alternativercomputerclub.de.vu [ - Answer - Quote - Direct link - ] |
2006-09-19, 22:07 h Ralf27 Posts: 2779 User |
Nochwas:code:move rpS&,20,45:Text rpS&, SADD(STR$(TIMER-t!)+CHR$(0)),LEN(STR$(TIMER-t!)) move rpS&,20,55:Text rpS&, SADD(STR$(myseconds%)+CHR$(0)),LEN(STR$(myseconds%)) Hier wird das CHR$(0) nun wirklich nicht benötigt. Die länge wird ja hinter der Funktion angegeben. -- http://www.alternativercomputerclub.de.vu [ - Answer - Quote - Direct link - ] |
2006-09-19, 22:56 h MaikG Posts: 5172 User |
>Reicht es aus einfach MEMF_CLEAR& anzugeben, wenn man einen >beliebigen Speicherbereich benötigt? Bzw. wird dann immer Fast >bevorzugt? Oder muß man da doch noch angeben was man will? Ja, warum nicht? Fast hat höhere Priorität, daher nehme ich das an. >Hier wird das CHR$(0) nun wirklich nicht benötigt. Die länge wird >ja hinter der Funktion angegeben. Mh, mag sein. Aber wir sind ja noch nicht bei der Optimierung sondern bei der Grundfunktion :-) [ - Answer - Quote - Direct link - ] |
2006-09-20, 12:35 h Mad_Dog Posts: 1944 User |
Zitat: Ja. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2006-09-20, 12:51 h whose Posts: 2156 User |
Zitat: Prinzipiell siehts eigentlich gut aus, in der C-Variante funktioniert es so problemlos. Ersetz doch mal code:junk&=WaitPort&(timerport&) WHILE TimerMsg&=GetMsg&(timerport&) WEND gegen code:WaitIO(tr&) und laß die WHILE-Schleife mit GetMsg() weg. Sobald Du die Funktionalität hast, solltest Du das code:IF PEEKL(eclockval&+ev_lo%)+diff& < PEEKL(eclockval&+ev_lo%) THEN POKEL(eclockval&+ev_hi%),PEEKL(eclockval&+ev_hi%)+1 ELSE POKEL(eclockval&+ev_lo%),PEEKL(eclockval&+ev_lo%)+diff& END IF noch durch die (korrekte) Variante aus der Sample-Schleife ersetzen, also gegen das hier: code:.newLow&=PEEKL(eclockval&+ev_lo%)+diff& IF newLow&<PEEKL(eclockval&+ev_lo%) THEN POKEL(eclockval&+ev_hi%),PEEKL(eclockval&+ev_hi%)+1 POKEL(eclockval&+ev_lo%),newLow& Ersteres war ein Fehler von mir, da hatte ich vergessen, ev_lo auf jeden Fall mit der Differenz zu addieren. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-20, 13:35 h Holger Posts: 8116 User |
Also die vielen PEEKs und POKEs sind nicht gerade ein Gewinn für die Lesbarkeit des Programms. Da die EClockVal-Struktur nur ein einziges Mal am Anfang an ReadEClock&() übergeben wird, und im Rest des Programms ausschließlich für Basic-Zugriffe genutzt wird, liest sich das Programm mit Sicherheit besser, wenn man Basic-Variablen nutzt. Also Basic code:Und dann überall im Programm PEEKL(eclockval&+ev_lo%) durch myEClockValLo& und PEEKL(eclockval&+ev_hi%) durch myEClockValHi&, sowie POKEL eclockval&+ev_lo%, xxx durch myEClockValLo&=xxx und POKEL eclockval&+ev_hi%, xxx durch myEClockValHi&=xxx ersetzen.DIM myEClockVal&(2) ticks&=ReadEClock&(VARPTR(myEClockVal&(0))) myEClockValHi&=myEClockVal&(0) myEClockValLo&=myEClockVal&(1) Das erlaubt dann noch weitere Vereinfachungen, wie das Ersetzen von POKEL(eclockval&+ev_hi%),PEEKL(eclockval&+ev_hi%)+1 durch INCR myEClockValHi&. Zitat: Leider funktioniert das so auch nicht. Diese Art von Überlauftest funktioniert nur, wenn die Zahl als vorzeichenlos (ULONG) behandelt wird. Denn der Überlauf muss als solcher beim Übergang von 0xFFFFFFFF nach 0x00000000 erkannt werden. Da Basic aber diese Variablen immer als vorzeichenbehaftet betrachtet, wird der Vergleich beim Übergang von 0x7FFFFFFF nach 0x80000000 positiv. Inkl. der oben vorgeschlagenen Lesbarkeitsverbesserung, müsste der korrekte Code so aussehen: Basic code:newLow&=myEClockValLo& + diff& IF newLow& >= 0 AND myEClockValLo& < 0 THEN INCR myEClockValHi& myEClockValLo&=newLow& mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ Dieser Beitrag wurde von Holger am 20.09.2006 um 13:37 Uhr geändert. ] [ - Answer - Quote - Direct link - ] |
2006-09-20, 16:19 h whose Posts: 2156 User |
Zitat: Ah so, sorry, ich dachte, MB wäre da schon etwas weiter gewesen als AmigaBASIC. ACE z.B. kennt auch vorzeichenlose Integer-Variablen, daher dachte ich, das wäre bei MB auch so. Wiederum danke für die Korrektur. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-20, 23:07 h MaikG Posts: 5172 User |
Also so? Crasht trotzdem, kein Hit, aber Cyberguard meldet 8000000B. code:DIM myEClockVal&(2) ticks&=ReadEClock&(VARPTR(myEClockVal&(0))) myEClockValHi&=myEClockVal&(0) myEClockValLo&=myEClockVal&(1) Intervall%=8000 diff&=ticks&/Intervall% newLow&=myEClockValLo& + diff& IF newLow& >= 0 AND myEClockValLo& < 0 THEN INCR myEClockValHi& myEClockValLo&=newLow& POKEW tr& + tr_node% + IORequestio_Command%, TR_ADDREQUEST& POKEL tr& + tr_time% + tv_secs%, myEClockValHi& POKEL tr& + tr_time% + tv_micro%, myEClockValLo& SendIO&(tr&) t!=TIMER WHILE Repeat1%<Intervall% junk&=WaitIO&(tr&) REM neu newLow&=myEClockValLo& + diff& IF newLow& >= 0 AND myEClockValLo& < 0 THEN INCR myEClockValHi& myEClockValLo&=newLow& POKEW tr& + tr_node% + IORequestio_Command%, TR_ADDREQUEST& POKEL tr& + tr_time% + tv_secs%, myEClockValHi& POKEL tr& + tr_time% + tv_micro%, myEClockValLo& SendIO&(tr&) INCR repeat1% INCR mycount%:IF mycount%=8000 THEN mycount%=0:INCR myseconds%:move rpS&,20,25:Text rpS&, SADD(TIME$+CHR$(0)),8 REM sa&=PEEKB(&hBFE101)<<8 REM IF sa&>&H7FFF THEN sa&=sa& OR &HFFFF0000& REM bla%=goertzel%(sa&) WEND [ - Answer - Quote - Direct link - ] |
2006-09-21, 12:10 h whose Posts: 2156 User |
@MaikG: Hm, da weiß ich im Moment auch nicht weiter, müßte jemand helfen, der sich mit den Eigenheiten von MB auskennt. Prinzipiell sollte es laufen. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-21, 13:04 h Holger Posts: 8116 User |
@MaikG: Hilft ja nix, wenn wir den Rest des Programms nicht kennen. Außerdem könntest Du einfach mal versuchen, die Zeile herauszufinden, bis zu der das Programm noch läuft. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2006-09-21, 13:06 h Holger Posts: 8116 User |
Zitat:Vielleicht kennt es ja sowas, aber wie soll man das ohne Handbuch herausfinden? Zumindest müsste man ja die gewünschte Vorzeichenlosigkeit irgendwie deklarieren. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2006-09-21, 14:53 h MaikG Posts: 5172 User |
>Hilft ja nix, wenn wir den Rest des Programms nicht kennen. Gut, ist zwar schon ohne das neue so gelaufen aber steht unten. >Außerdem könntest Du einfach mal versuchen, die Zeile >herauszufinden, bis zu der das Programm noch läuft. ich hab den Text mit reingenommen und dieser wird nicht mehr ausgegeben, aber ich kann das noch genauer versuchen. Wie man MaxonBasic dazu bewegen kann das vorzeichen nicht zu benutzen weiss ich nicht. Evtl. direkt mit Peek und Poke arbeiten aber für MaxonBasic selbst ist es immer vorzeichenbehaftet. code:REM $HEAPDYNAMIC=2048 REM $KEEP=2048 REM $MATHSTACK=8192 REM $MINSTACK=16384 REM $Nolibrary REM $Nolines REM $NoOverflow REM $NOEVENT REM $NoWindow REM $NoADDICON REM $NOARRAY REM $NOAUTODIM REM $NOERRORS REM $NOVARCHECKS DEFINT A-Z '$INCLUDE Exec.bh '$INCLUDE Timer.bh '$INCLUDE Graphics.bh '$INCLUDE Intuition.bh '$INCLUDE GadTools.bh LIBRARY OPEN "graphics.library", 37 LIBRARY OPEN "intuition.library", 37 LIBRARY OPEN "gadtools.library", 37 LIBRARY OPEN "exec.library", 37 DIM SHARED tl&(40), rpS& DIM SHARED junk&,dummy$ CONST SAMPLING_RATE%=8000 REM CONST MAX_BINS%=8 CONST GOERTZEL_N%=92 DIM SHARED q1#(7) 'double q1[ MAX_BINS ]; DIM SHARED q2#(7) 'double q2[ MAX_BINS ]; DIM SHARED r#(7) 'double r[ MAX_BINS ]; DIM SHARED freqs#(7) REM DIM SHARED sample_count% 'INT sample_count; DIM SHARED coefs#(7) DIM SHARED row_col_ascii_codes$(3,3) SUB delete_timer(BYVAL tr&) STATIC tp& IF tr& <> NULL& THEN tp& = PEEKL(tr& + tr_node% + IORequestio_Message% + mn_ReplyPort%) IF tp& <> 0 THEN DeleteMsgPort tp& CloseDevice tr& DeleteIORequest tr& END IF END SUB freqs#(0)=697 freqs#(1)=770 freqs#(2)=852 freqs#(3)=941 freqs#(4)=1209 freqs#(5)=1336 freqs#(6)=1477 freqs#(7)=1633 row_col_ascii_codes$(0,0)="1" row_col_ascii_codes$(0,1)="2" row_col_ascii_codes$(0,2)="3" row_col_ascii_codes$(0,3)="A" row_col_ascii_codes$(1,0)="4" row_col_ascii_codes$(1,1)="5" row_col_ascii_codes$(1,2)="6" row_col_ascii_codes$(1,3)="B" row_col_ascii_codes$(2,0)="7" row_col_ascii_codes$(2,1)="8" row_col_ascii_codes$(2,2)="9" row_col_ascii_codes$(2,3)="C" row_col_ascii_codes$(3,0)="*" row_col_ascii_codes$(3,1)="0" row_col_ascii_codes$(3,2)="#" row_col_ascii_codes$(3,3)="D" FOR n%=0 TO 7 REM MAX_BINS%-1 coefs#(n%)=2.0#*COS(2.0*3.141592654 * freqs#(n%)/SAMPLING_RATE%) NEXT n% ' post_testing ' This is where we look at the bins and decide if we have a valid signal. SUB post_testing STATIC row%, col%, see_digit%, peak_count%, max_index%, i% STATIC maxval#,t# ' /* Find the largest in the row group. */ row%=0 maxval#=0.0 FOR i%=0 TO 3 IF r#(i%)>maxval# THEN maxval#=r#(i%):row%=i% NEXT i% ' /* Find the largest in the column group. */ col%=4 maxval#=0.0 FOR i%=4 TO 7 IF r#(i%)>maxval# THEN maxval#=r#(i%):col%=i% NEXT i% ' /* Check FOR minimum energy */ REM IF r#(row%)>=4E5 AND r#(col%)>=4E5 THEN see_digit% = TRUE& IF r#(row%)<4E5 OR r#(col%)<4E5 THEN GOTO 2 see_digit%=TRUE& IF r#(col%)>r#(row%) THEN max_index%=col% IF r#(row%)<(r#(col%)*0.398) THEN see_digit% = FALSE& REM twist > 4dB, error ELSE max_index%=row% IF r#(col%)<(r#(row%)*0.158) THEN see_digit% = FALSE& REM twist > 8db, error END IF REM 1*10^9 IF r#(max_index%)>1E9 THEN t#=r#(max_index%)*0.158 ELSE t#=r#(max_index%)*0.010 peak_count%=0 FOR i%=0 TO 7 IF r#(i%)>t# THEN INCR peak_count% NEXT i% IF peak_count%>2 THEN see_digit%=FALSE& IF see_digit% THEN move rpS&,20,50:Text rpS&, SADD(row_col_ascii_codes$(row%,col%-4)+CHR$(0)),1 2 END SUB ' * goertzel FUNCTION goertzel%(BYVAL sample%) STATIC q0#, i% IF sample_count%<GOERTZEL_N% THEN INCR sample_count% FOR i%=0 TO 7 REM MAX_BINS%-1 q0#=coefs#(i%)*q1#(i%)-q2#(i%)+sample% q2#(i%)=q1#(i%) q1#(i%)=q0# NEXT i% ELSE FOR i%=0 TO 7 REM MAX_BINS%-1 r#(i%)=q1#(i%)*q1#(i%) + q2#(i%)*q2#(i%) - coefs#(i%)*q1#(i%)*q2#(i%) q1#(i%)=0.0 q2#(i%)=0.0 NEXT i% post_testing sample_count%=0 END IF END FUNCTION TAGLIST VARPTR(tl&(0)), _ WA_Title&, "DTMF erkennung", _ WA_Width&, 600, _ WA_InnerHeight&, 100, _ WA_Top&, 16, _ WA_Left&, 0, _ WA_Activate&, TRUE&, _ WA_DragBar&, TRUE&, _ WA_DepthGadget&, TRUE&, _ WA_CloseGadget&, TRUE&, _ WA_SizeGadget&, TRUE&, _ WA_SmartRefresh&, TRUE&, _ WA_NoCareRefresh&, TRUE&, _ WA_IDCMP&, IDCMP_CLOSEWINDOW&, _ WA_MinWidth&, 631, _ WA_MinHeight&, 100, _ TAG_END& winS& = OpenWindowTagList&(NULL&, VARPTR(tl&(0))) rpS&=PEEKL(winS&+rport%) POKEB &hBFE301,0 REM tr&=create_timer&() timerport& = CreateMsgPort&() IF timerport& <> NULL& THEN tr& = CreateIORequest&(timerport&, timerequest_sizeof%) IF tr& <> NULL& THEN IF OpenDevice&(SADD("timer.device" + CHR$(0)), UNIT_WAITUNTIL&, tr&, 0)<> 0 THEN delete_timer tr&:GOTO 5 ELSE DeleteMsgPort timerport& END IF END IF REM eclockval&=AllocMem&(EClockVal_sizeof%,MEMF_CLEAR&) REM ticks&=ReadEClock&(eclockval&) DIM myEClockVal&(2) ticks&=ReadEClock&(VARPTR(myEClockVal&(0))) myEClockValHi&=myEClockVal&(0) myEClockValLo&=myEClockVal&(1) Intervall%=8000 diff&=ticks&/Intervall% newLow&=myEClockValLo& + diff& IF newLow& >= 0 AND myEClockValLo& < 0 THEN INCR myEClockValHi& myEClockValLo&=newLow& POKEW tr& + tr_node% + IORequestio_Command%, TR_ADDREQUEST& POKEL tr& + tr_time% + tv_secs%, myEClockValHi& POKEL tr& + tr_time% + tv_micro%, myEClockValLo& SendIO&(tr&) t!=TIMER WHILE Repeat1%<Intervall% junk&=WaitIO&(tr&) REM neu newLow&=myEClockValLo& + diff& IF newLow& >= 0 AND myEClockValLo& < 0 THEN INCR myEClockValHi& myEClockValLo&=newLow& POKEW tr& + tr_node% + IORequestio_Command%, TR_ADDREQUEST& POKEL tr& + tr_time% + tv_secs%, myEClockValHi& POKEL tr& + tr_time% + tv_micro%, myEClockValLo& SendIO&(tr&) INCR repeat1% INCR mycount%:IF mycount%=8000 THEN mycount%=0:INCR myseconds% rem :move rpS&,20,25:Text rpS&, SADD(TIME$+CHR$(0)),8 REM sa&=PEEKB(&hBFE101)<<8 REM IF sa&>&H7FFF THEN sa&=sa& OR &HFFFF0000& REM bla%=goertzel%(sa&) WEND move rpS&,20,45:Text rpS&, SADD(STR$(TIMER-t!)+CHR$(0)),LEN(STR$(TIMER-t!)) move rpS&,20,55:Text rpS&, SADD(STR$(myseconds%)+CHR$(0)),LEN(STR$(myseconds%)) REM AbortIO&(tr&) REM junk&=WaitIO&(tr&) REM FreeMem eclockval&,EClockVal_sizeof% terminatedS%=0 WHILE terminatedS%=0 junk&= xWait&(1& << PEEKB(PEEKL(winS&+UserPort%)+mp_SigBit%)) DO imsgS& = GT_GetIMsg(PEEKL(winS&+UserPort%)) IF imsgS&=0 THEN EXIT LOOP imsgClassS& =PEEKL(imsgS&+Class%) GT_ReplyIMsg imsgS& SELECT CASE imsgClassS& CASE IDCMP_CLOSEWINDOW&: terminatedS% = 1 CASE IDCMP_REFRESHWINDOW&: GT_BeginRefresh winS& GT_EndRefresh winS&, TRUE& END SELECT LOOP UNTIL terminatedS% WEND 5 CloseWindow winS& END Nachtrag: Stürzt bei ReadEClock ab. [ Dieser Beitrag wurde von MaikG am 21.09.2006 um 15:38 Uhr geändert. ] [ - Answer - Quote - Direct link - ] |
2006-09-21, 18:27 h Holger Posts: 8116 User |
Zitat: ReadEClock ist ein Art Library-Funktion des timer.device. Um die aus MaxonBasic heraus aufzurufen, muss MaxonBasic die Basisadresse der Library kennen, man kann aber ein device nicht wie eine Library öffnen. Wenn ich mein eigentlich nicht vorhandenes Wissen über MaxonBasic zusammenkratze, geht das so: Nach dem erfolgreichen Öffnen des timer device (und nur dann), teilst Du MaxonBasic die Adresse via code:mit und bevor Du das device schließt, teilst Du MaxonBasic mit, dass diese Library nicht mehr zur Verfügung steht (damit MaxonBasic nicht etwa versucht, das device wie eine Library automatisch zu schließen).LIBRARY VARPTR "timer.device", PEEKL(tr& + IOStdReqio_Device%) code:Kann das aber nicht testen, da das Programm den Rahmen der Demoversion sprengt.LIBRARY VARPTR "timer.device", NULL& mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2006-09-21, 21:41 h whose Posts: 2156 User |
Zitat: Ich seh schon, ich sollte mal die Antifalten-Gurkenscheiben von den Augen nehmen Ich hab glatt übersehen, daß das fehlt. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Answer - Quote - Direct link - ] |
2006-09-21, 22:58 h MaikG Posts: 5172 User |
>ReadEClock ist ein Art Library-Funktion des timer.device. Um die aus >MaxonBasic heraus aufzurufen, muss MaxonBasic die Basisadresse der >Library kennen, man kann aber ein device nicht wie eine Library >öffnen. Ah, dafür ist das mit Library VARPTR. >Nach dem erfolgreichen Öffnen des timer device (und nur dann), teilst Du MaxonBasic die Adresse via > code: > LIBRARY VARPTR "timer.device", PEEKL(tr& + IOStdReqio_Device%) >mit und bevor Du das device schließt, teilst Du MaxonBasic mit, dass diese Library nicht mehr zur Verfügung steht (damit MaxonBasic nicht etwa versucht, das device wie eine Library automatisch zu schließen). > code: > LIBRARY VARPTR "timer.device", NULL& Klingt korrekt, das hab ich so mit was anderem schon gesehen. [ - Answer - Quote - Direct link - ] |
2006-09-22, 09:03 h MaikG Posts: 5172 User |
Stürzt nicht mehr ab, aber ich glaub auch nicht das es Funktioniert. Bei einem Intervall von 8000 HZ läuft die Schleife 183.1758 sekunden -das kann ja nicht stimmen oder? [ - Answer - Quote - Direct link - ] |
2006-09-22, 12:27 h whose Posts: 2156 User |
Zitat: Nein, kann es eigentlich nicht. Es sei denn, irgendwas in dem Programm läuft noch daneben oder es läuft schlicht zu langsam. Letzteres kann ich mir aber nicht so recht vorstellen. Grüße -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ Dieser Beitrag wurde von whose am 22.09.2006 um 12:31 Uhr geändert. ] [ - Answer - Quote - Direct link - ] |
2006-09-22, 13:22 h Holger Posts: 8116 User |
Zitat: Du musst auch UNIT_WAITECLOCK beim Öffnen des device angeben, wenn Du UNIT_WAITECLOCK und nicht UNIT_WAITUNTIL verwenden willst. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2006-09-22, 14:53 h MaikG Posts: 5172 User |
Oh, simmt nun sind es 1.648439 - mit goertzel also 1,0 müssten es sein. Wie muss ich das machen wenn ich 20sekunden will? Um der Schleife noch eine geht nicht. [ - Answer - Quote - Direct link - ] |
First 4 5 6 7 8 -9- 10 11 | [ - Post reply - ] |
amiga-news.de Forum > Programmierung > Tonerkennung | [ - Search - New posts - Register - Login - ] |
Masthead |
Privacy policy |
Netiquette |
Advertising |
Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved. |