amiga-news DEUTSCHE VERSION
.
Links| Forums| Comments| Report news
.
Chat| Polls| Newsticker| Archive
.

amiga-news.de Forum > Programmierung > Tonerkennung [ - Search - New posts - Register - Login - ]

1 2 -3- 4 5 6 7 8 Last [ - Post reply - ]

2006-08-31, 14:52 h

bubblebobble
Posts: 707
User
Was für eine Idee ?
Wir haben das Problem hier für dich quasi gelöst und beschrieben, wie man es macht, inkl. Sourcecode und Verweis auf eine externe Library.

Was noch ? Danach käme nur noch das für dich in Maxon Basic zu implementieren. Aber ich denke das musst du schon selbst hinbekommen. Sonst geht es eben nicht.

--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]

2006-08-31, 16:55 h

Holger
Posts: 8116
User
Zitat:
Original von MaikG:
Hab schon überlegt ob man ein Sample mit dem Basic Programm
in die Ram Disk legt und dann mit einem C Programm das Sample
auswertet.

Wozu soll diese komplizierte Vorgehensweise gut sein? Da kann das C Programm auch den Parallelport selber abfragen und Deinem Basic-Programm die decodierten Tasten übergeben.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-08-31, 18:31 h

MaikG
Posts: 5172
User
>Was für eine Idee ?
>Wir haben das Problem hier für dich quasi gelöst und beschrieben,
>wie man es macht, inkl. Sourcecode und Verweis auf eine externe
>Library.

Ich bin zu blöd um Irgendein Source hier umzuwandeln, das ist
zuviel und vorallem Funktionen womit ich noch nie zu tun habe.

Der verweiss auf die Externe Library ist gut, nur lässt
sich diese nicht benutzen - was das Problem ist.
Vermutlich ist die .fd Datei die dem Archiv beiligt Fehlerhaft.
Deswegen will MaxonBasic einen Parameter mehr als man eigentlich,
von den AutoDocs her übergeben muss.
Auch wenn man den zusätzlichen Parameter 0 gibt geht es nicht.


Beispiel: eFFTcalc(handle)
MaxonBasic sagt es muss so aussehen: eFFTcalc(handle, XXX)


>Wozu soll diese komplizierte Vorgehensweise gut sein? Da kann das
>C Programm auch den Parallelport selber abfragen und Deinem
>Basic-Programm die decodierten Tasten übergeben.

mh, doch das könnte Theoretisch auch gehen.

[ - Answer - Quote - Direct link - ]

2006-09-01, 13:01 h

Mad_Dog
Posts: 1944
User
Zitat:
Original von MaikG:

Ich bin zu blöd um Irgendein Source hier umzuwandeln, das ist
zuviel und vorallem Funktionen womit ich noch nie zu tun habe.


Ich vermute mal, Du bist nicht zu blöd, sondern nur zu ungeduldig. Lern lieber erstmal richtig Programmieren, bevor Du an solche Sachen rangehst (ist nicht böse gemeint).

Und vor allem sollest Du erst ein Problem ganz genau analysieren, bevor Du auch nur eine Zeile Code schreibst.

--
http://www.norman-interactive.com

[ - Answer - Quote - Direct link - ]

2006-09-01, 15:22 h

Holger
Posts: 8116
User
@MaikG:
Ich hatte Dir, nur noch mal als Hinweis, einen Link zu einem DTMF-Decoder (basierend auf dem Goertzel-Algorithmus) gepostet, der komplett ohne zusätzliche Bibliotheken auskommt. Ich kann Dir allerdings nicht versprechen, dass es irgendwie leichter wäre, denn C-code zu verstehen und in eine andere Sprache zu konvertieren, ist nunmal nicht einfach.

Der Beispielcode muss nur 8000 Mal pro Sekunde mit einem Samplewert gefüttert werden, und spuckt die decodierten Zeichen aus. Den kann man umsetzen, ohne mit .fd-Files rumhantieren zu müssen...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-09-01, 15:52 h

Mad_Dog
Posts: 1944
User
Zitat:
Original von Holger:

Der Beispielcode muss nur 8000 Mal pro Sekunde mit einem Samplewert gefüttert werden, und spuckt die decodierten Zeichen aus. Den kann man umsetzen, ohne mit .fd-Files rumhantieren zu müssen...


Sollte man nicht immer mit der doppelten Frequenz des Eingangssignals abtasten (so habe ich das jedenfalls gelernt)?
Wenn Du mit 8kHz abtastest, kannst Du maximal eine Frequenz von 4kHz sauber abtasten...

Siehe auch http://de.wikipedia.org/wiki/Abtasttheorem

--
http://www.norman-interactive.com

[ Dieser Beitrag wurde von Mad_Dog am 01.09.2006 um 15:53 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2006-09-01, 16:46 h

Holger
Posts: 8116
User
Zitat:
Original von Mad_Dog:
Sollte man nicht immer mit der doppelten Frequenz des Eingangssignals abtasten (so habe ich das jedenfalls gelernt)?
Wenn Du mit 8kHz abtastest, kannst Du maximal eine Frequenz von 4kHz sauber abtasten...

Zum Erkennen von Signaltönen nimmt man noch ein bisschen mehr mit, um Störungen leichter erkennen zu können. Aber bei einem Maximum von einer Signalkombination von 941 Hz und 1633 Hz reicht das locker aus...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-09-01, 16:56 h

Mad_Dog
Posts: 1944
User
Zitat:
Original von Holger:
Zitat:
Original von Mad_Dog:
Sollte man nicht immer mit der doppelten Frequenz des Eingangssignals abtasten (so habe ich das jedenfalls gelernt)?
Wenn Du mit 8kHz abtastest, kannst Du maximal eine Frequenz von 4kHz sauber abtasten...

Zum Erkennen von Signaltönen nimmt man noch ein bisschen mehr mit, um Störungen leichter erkennen zu können. Aber bei einem Maximum von einer Signalkombination von 941 Hz und 1633 Hz reicht das locker aus...

Aha... wusste nicht, in welchem Frequenzbereich sich das bewegt, aber bei wikipedia ist es auch beschrieben: http://de.wikipedia.org/wiki/DTMF

Für 1633Hz würden auch 4kHz Samplingfrequenz reichen.

BTW.: Ich kann mich vage an ein Programm von einer Demo CD erinnern, welches in Echtzeit von dem gesampelten Sound vom Parallelportsampler eine Spektralanalyse gemacht hat (also braucht's wohl doch nicht soviel Rechenpower...). Mal schauen, vielleicht find ich's ja mal wieder. ;-)

--
http://www.norman-interactive.com

[ - Answer - Quote - Direct link - ]

2006-09-01, 18:24 h

MaikG
Posts: 5172
User
>Ich vermute mal, Du bist nicht zu blöd, sondern nur zu ungeduldig.

Ist relativ zu sehen, wenn ich es in einem Jahr übersetzt habe
nützt das mir gar nichts mehr. Dann kann ich gleich ganz andere
wege gehen.

>Lern lieber erstmal richtig Programmieren, bevor Du an solche Sachen
>rangehst (ist nicht böse gemeint).
>Und vor allem sollest Du erst ein Problem ganz genau analysieren,
>bevor Du auch nur eine Zeile Code schreibst.

Was soll ich da analysieren?
Ich habe bei der voice.library das selbe gemacht und diese Library
funktionierte dann auch.
Also muss ja bei der blöden easyFFT.library die .fd Datei verkehrt
sein.

>Ich hatte Dir, nur noch mal als Hinweis, einen Link zu einem
>DTMF-Decoder (basierend auf dem Goertzel-Algorithmus) gepostet,
>der komplett ohne zusätzliche Bibliotheken auskommt.
>Ich kann Dir allerdings nicht versprechen, dass es irgendwie
>leichter wäre, denn C-code zu verstehen und in eine andere Sprache
>zu konvertieren, ist nunmal nicht einfach.

Library aufrufe sind normalerweise nicht schlimm. Kompliziertes
C umzuwandeln schon.

>BTW.: Ich kann mich vage an ein Programm von einer Demo CD erinnern,
>welches in Echtzeit von dem gesampelten Sound vom Parallelportsampler
>eine Spektralanalyse gemacht hat (also braucht's wohl doch nicht
>soviel Rechenpower...). Mal schauen, vielleicht find ich's ja mal
>wieder. ;-)

Wenns das auch in eine Datei übergeben kann wäre das
erstmal genau das richtige.

[ - Answer - Quote - Direct link - ]

2006-09-01, 18:47 h

Holger
Posts: 8116
User
Zitat:
Original von Mad_Dog:
BTW.: Ich kann mich vage an ein Programm von einer Demo CD erinnern, welches in Echtzeit von dem gesampelten Sound vom Parallelportsampler eine Spektralanalyse gemacht hat (also braucht's wohl doch nicht soviel Rechenpower...). Mal schauen, vielleicht find ich's ja mal wieder. ;-)


und da lag der source-code bei?
Die Frequenzanalyse via FFT ist auch nicht unbedingt rechenintensiv, insb. wenn man nur nen Demo-Effekt implementieren will. Da analysiert man eh nur kleine Blöcke und ignorierten die restlichen Daten. Bei max. 50 sichtbaren Resultaten ist Präzision nicht so wichtig.

Letzendlich ist aber ein für eine bestimmte Aufgabe angepasster Algorithmus trotzdem besser. Insbesondere, weil es mit der Frequenzanalyse ja noch nicht getan ist. Du musst für DTFM ja auch noch die Werte miteinander vergleichen und noise und twist test durchführen.

Da ist ein Stück code, das bei 150 Zeilen bereits alles komplett enthält, eigentlich kaum zu toppen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-09-01, 18:52 h

Holger
Posts: 8116
User
Zitat:
Original von MaikG:
Library aufrufe sind normalerweise nicht schlimm. Kompliziertes
C umzuwandeln schon.


Das Beispiel ist nicht kompliziert. for-Schleifen, if-Anweisungen, Zuweisungen und Grundrechenarten, ca. 150 Zeilen (inkl. Kommentare), das war's auch schon.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-09-01, 23:04 h

MaikG
Posts: 5172
User
>Das Beispiel ist nicht kompliziert. for-Schleifen, if-Anweisungen,
>Zuweisungen und Grundrechenarten, ca. 150 Zeilen (inkl. Kommentare),
>das war's auch schon.


Für jemanden der C richtig kann ist es nicht kompliziert, für
einen der nur ganz simple C sachen kann schon.

[ - Answer - Quote - Direct link - ]

2006-09-02, 11:13 h

MaikG
Posts: 5172
User
So das währe der DTMF Code in Basic:
Er lässt sich Compilieren, ich hab aber noch einige fragen:
1. Die Variablen die oben bei C definiert werden sind für alle Unterprogramme zugänglich?
2. In freqs werden nur 8 Werte abgelegt bei Basic geht fängt ein Array von 0 an, ist es jetzt richtig
die werte von 1-8 zu schreiben oder sollten diese von 0-7 gehen?
3. Bei FOR ist das ähnlich es geht von 0 bis 8 ist das korrekt oder müsste es von 0 bis 8-1 heissen?
4. z.B. 4.0e5 entspricht das 4.0^5 ?
5. Wie gebe ich da überhaupt meinen Sample hinein? sample% kann ja kein Zeiger auf ein Speicherbereich
sein.


code:
REM aktualisiert 04.09.2006 - 11:53

REM $Nolibrary
REM $Nolines
REM $NoOverflow
REM $NOEVENT

DEFINT A-Z

'$INCLUDE Exec.bh
'$INCLUDE Timer.bh

REM $INCLUDE BLib/ExecSupport.bas

LIBRARY OPEN "exec.library", LIBRARY_MINIMUM&

CONST SECSPERMIN& = 60
CONST SECSPERHOUR& = 3600
CONST SECSPERDAY& = 86400

DIM currentval(timeval_sizeof  2)
DIM SHARED junk&,dummy$

FUNCTION create_timer&(BYVAL unit&)
    STATIC r&, timerport&, timerIO&
    create_timer& = NULL&
    timerport& = CreatePort&(NULL&, 0)
    IF timerport& <> NULL& THEN
        timerIO& = CreateExtIO&(timerport&, timerequest_sizeof)
        IF timerIO& <> NULL& THEN
            r& = OpenDevice&(SADD("timer.device" + CHR$(0)), unit&, timerIO&, 0)
            IF r& = 0 THEN
                create_timer& = timerIO&
            ELSE
                delete_timer timerIO&
            END IF
        ELSE
            DeletePort timerport&
        END IF
    END IF
END FUNCTION

SUB delete_timer(BYVAL tr&)
    STATIC tp&
    IF tr& <> NULL& THEN
        tp& = PEEKL(tr& + tr_node + IORequestio_Message + mn_ReplyPort)
        IF tp& <> 0 THEN DeletePort tp&
        CloseDevice tr&
        DeleteExtIO tr&
    END IF
END SUB

FUNCTION time_delay(BYVAL tv&, BYVAL unit&)
    STATIC tr&
    time_delay = FALSE&
    tr& = create_timer&(unit&)
    IF tr& <> NULL& THEN
        wait_for_timer tr&, tv&
        delete_timer tr&
        time_delay = TRUE&
    END IF
END FUNCTION

SUB wait_for_timer(BYVAL tr&, BYVAL tv&)
    POKEW tr& + tr_node + IORequestio_Command, TR_ADDREQUEST&
    CopyMem tv&, tr& + tr_time, timeval_sizeof    ' structure assignment
    junk& = DoIO&(tr&)
END SUB

CONST SAMPLING_RATE%=8000
CONST MAX_BINS%=8
CONST GOERTZEL_N%=92

DIM SHARED q1#(MAX_BINS%) 'double      q1[ MAX_BINS ];
DIM SHARED q2#(MAX_BINS%) 'double      q2[ MAX_BINS ];
DIM SHARED r#(MAX_BINS%)  'double      r[ MAX_BINS ];
DIM SHARED freqs#(MAX_BINS%)
DIM SHARED sample_count% 'INT         sample_count;
DIM SHARED coefs#(MAX_BINS%)
DIM SHARED row_col_ascii_codes$(4,4)


' double      freqs[ MAX_BINS] = 
'    697,
'    770,
'    852,
'    941,
'    1209,
'   1336,
'    1477,
'    1633
'};

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"


'double      coefs[ MAX_BINS ] ;
' *  calc_coeffs

'void
'calc_coeffs()
'{
'int n;
'
'  for(n = 0; n < MAX_BINS; n++)
'  {
'    coefs[n] = 2.0 * cos(2.0 * 3.141592654 * freqs[n] / SAMPLING_RATE);
'  }
'
'}

REM SUB calc_coeffs
 FOR n%=0 TO 7 REM MAX_BINS%-1
  coefs#(n%)=2.0*COS(2.0*3.141592654 * freqs#(n%)/SAMPLING_RATE%)
 NEXT n%
REM END SUB

' *  post_testing
' * This is where we look at the bins and decide if we have a valid signal.

'void
'post_testing()

'{
'int         row, col, see_digit;
'int         peak_count, max_index;
'double      maxval, t;
'int         i;

SUB post_testing
STATIC row%, col%, see_digit%
STATIC peak_count%, max_index%, i%
STATIC maxval#,t#


 'char *  row_col_ascii_codes[4][4] = {
 '       {"1", "2", "3", "A"},
 '       {"4", "5", "6", "B"},
 '       {"7", "8", "9", "C"},
 '       {"*", "0", "#", "D"}};


'    /* Find the largest in the row group. */
'    row = 0;
'     maxval = 0.0;
'     for ( i=0; i<4; i++ )
'     {
'         if ( r[i] > maxval )
'         {
'             maxval = r[i];
'             row = i;
'         }
'     }

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; i<8; i++ )
'     {
'         if ( r[i] > maxval )
'         {
'             maxval = r[i];
'             col = i;
'         }
'     }

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 */
'   if ( r[row] < 4.0e5 )   /* 2.0e5 ... 1.0e8 no change */
'    {
'        /* energy not high enough */
'    }
'    else if ( r[col] < 4.0e5 )
'    {
'        /* energy not high enough */
'    }
'    else
'    {
'        see_digit = TRUE;


    IF r#(row%)<4*10^5 THEN
     dummy$="energy not high enough"
     ELSEIF r#(col%)<4*10^5 THEN dummy$="energy NOT high enough"
     ELSE see_digit% = TRUE&
    END IF

'        if ( r[col] > r[row] )
'        {
'            /* Normal twist */
'            max_index = col;
'            if ( r[row] < (r[col] * 0.398) )    /* twist > 4dB, error */
'                see_digit = FALSE;
'        }
'        else /* if ( r[row] > r[col] ) */
'        {
'            /* Reverse twist */
'            max_index = row;
'            if ( r[col] < (r[row] * 0.158) )    /* twist > 8db, error */
'                see_digit = FALSE;
'        }

IF r#(col%)>r#(row%) THEN
 max_index%=col%
 IF r#(row%)<(r#(col%)*0.398) THEN see_digit% = FALSE&
 ELSE
 max_index%=row%
 IF r#(col%)<(r#(row%)*0.158) THEN see_digit% = FALSE&
END IF

'        if ( r[max_index] > 1.0e9 )
'            t = r[max_index] * 0.158;
'        else
'            t = r[max_index] * 0.010;
'
'        peak_count = 0;
'        for ( i=0; i<8; i++ )
'        {
'            if ( r[i] > t )
'                peak_count++;
'        }
'        if ( peak_count > 2 )
'            see_digit = FALSE;
'
'        if ( see_digit )
'        {
'            printf( "%s", row_col_ascii_codes[row][col-4] );
'            fflush(stdout);
'        }
'    }
'}

IF r#(max_index%)>1*10^9 THEN t#=r#(max_index%)*0.158 ELSE t#=r#(max_index%)*0.010

peak_count%=0

REM FOR i%=0 TO 7
REM IF r#(i%)>t# THEN INCR peak_count%
REM IF peak_count%>2 THEN see_digit%=FALSE&
REM IF see_digit% THEN LOCATE 2,2:PRINT row_col_ascii_codes$(row%,col%-4)
REM NEXT i%
 
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 LOCATE 2,2:PRINT row_col_ascii_codes$(row%,col%-4)





' *  goertzel
'void
'goertzel( int sample )
'{
'double      q0;
'ui32        i;
'
'    if ( sample_count < GOERTZEL_N )
'    {
'        sample_count++;
'        for ( i=0; i<MAX_BINS; i++ )
'        {
'            q0 = coefs[i] * q1[i] - q2[i] + sample;
'            q2[i] = q1[i];
'            q1[i] = q0;
'        }
'    }
'    else
'    {
'       for ( i=0; i<MAX_BINS; i++ )
'        {
'            r[i] = (q1[i] * q1[i]) + (q2[i] * q2[i]) - (coefs[i] * q1[i] * q2[i]);
'            q1[i] = 0.0;
'            q2[i] = 0.0;
'        }
'        post_testing();
'        sample_count = 0;
'    }
'}

END SUB


FUNCTION goertzek%(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


POKEB &hBFE301,0

1
IF PEEKB(&hBFE101)>180 THEN
 PRINT "jetzt"
 POKEL VARPTR(currentval(0)) + tv_secs, 0
 POKEL VARPTR(currentval(0)) + tv_micro, 000125 REM 500000=0.5s 000125=8000HZ
 2
junk = time_delay(VARPTR(currentval(0)), UNIT_MICROHZ&)
INCR mycount%:IF mycount%=8000 THEN LOCATE 1,1:PRINT TIME$:mycount%=0 
sa%=PEEKB(&hBFE101)
IF sa%>127 THEN
 sa%=sa%*128
 ELSEIF sa%<127 THEN sa%=sa%*(-128)
 ELSE sa%=0
 END IF
 bla%=goertzek%(sa%)
REM bla%=goertzek%(PEEKB(&hBFE101))
 IF INKEY$=CHR$(27) THEN 5
 GOTO 2
END IF
 IF INKEY$=CHR$(27) THEN 5
GOTO 1

5 END


[ Dieser Beitrag wurde von MaikG am 04.09.2006 um 11:55 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2006-09-02, 12:44 h

Holger
Posts: 8116
User
@MaikG:
Hab jetzt leider keine Zeit, um mir das Basic-Programm genauer anzusehen, aber auf Deine Fragen kann ich rasch eingehen.
Zitat:
1. Die Variablen die oben bei C definiert werden sind für alle Unterprogramme zugänglich?
Alle Variablen, die außerhalb einer Funktion stehen (auch das Hauptprogramm ist eine Funktion namens main) sind globale Variablen, also ja.
Zitat:
2. In freqs werden nur 8 Werte abgelegt bei Basic geht fängt ein Array von 0 an, ist es jetzt richtig
die werte von 1-8 zu schreiben oder sollten diese von 0-7 gehen?

In C fangen Indizes immer mit 0 an, wenn die Größe 8 ist, gehen die gültigen Indizes von 0-7.
Zitat:
3. Bei FOR ist das ähnlich es geht von 0 bis 8 ist das korrekt oder müsste es von 0 bis 8-1 heissen?
In for(;;) steht in C eine Bedingung, die vor der Ausführung überprüft wird, d.h. wenn dort i<8 steht, wird der Schleifenrumpf nicht mehr ausgeführt, wenn i==8 oder i>8 ist. Die Schleife iteriert also von 0 bis 7, also 8 Durchläufe (exakt wie beim array).
Zitat:
4. z.B. 4.0e5 entspricht das 4.0^5 ?
Nein, 4E5 ist identisch mit 4*10^5. Das sollte aber in Basic exakt genauso sein, das ist nunmal die wissenschaftliche Notation für Fließkommazahlen. Die solltest Du in Basic genauso hinschreiben können.
Zitat:
5. Wie gebe ich da überhaupt meinen Sample hinein? sample% kann ja kein Zeiger auf ein Speicherbereich sein.

Nein, ein einzelne Sample-Wert. Deshalb schrieb ich ja, Du musst die Funktion 8000 Mal pro Sekunde aufrufen (z.B. per Timer). Damit kannst Du zwischen den Aufrufen auch andere Dinge machen...

Übrigens gehört letztere Frage zu denen, die ich am Anfang auch gegrübelt habe. Der code ist wirklich unzureichen dokumentiert, aber dafür bist Du anscheinend schon weit gekommen, was meine These unterstützt, das er doch nicht so kompliziert ist ;) Wenn Du noch weitere Fragen hast, immer her damit.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-09-02, 16:17 h

MaikG
Posts: 5172
User
>In C fangen Indizes immer mit 0 an, wenn die Größe 8 ist, gehen die
>gültigen Indizes von 0-7.

#define MAX_BINS 8

double q1[ MAX_BINS ];


Heiss doch aber dim q1#(8), also hat man ein 9er Array erstellt
q1#(0) bis q1#(8) besitzen gültigkeit. Also 1 ist da irgendwie
überflüssig.


>Die Schleife iteriert also von 0 bis 7, also 8 Durchläufe
>(exakt wie beim array).

Okay dann also Max_Bins%-1

>Nein, ein einzelne Sample-Wert. Deshalb schrieb ich ja, Du musst
>die Funktion 8000 Mal pro Sekunde aufrufen (z.B. per Timer). Damit
>kannst Du zwischen den Aufrufen auch andere Dinge machen...

Also ich soll 8000 Mal(ob das Basic schafft?) einen Integer
wert übergeben also 0-255? Wie soll man aus einer einzelnen
Amplitude dann irgendeine Frequenz rausbekommen oder wird die
irgendwo zwischengespeichert?
Mit den Timer muss ich dann ja auch noch arbeiten, die Basic
eigene Funktion macht nur eine 200stel Sekunde wie ich feststellen
musste.

[ - Answer - Quote - Direct link - ]

2006-09-02, 18:32 h

Mad_Dog
Posts: 1944
User
So, ich hab jetzt das erwähnte Programm (bzw. mehrere Programme) gefunden, welche in Echtzeit FTT machen. Die Teile Stammen von der Demo-Gruppe Infect und waren auf der CD "Demos are forever" mit drauf.

Ich hab die Teile mal in ein Archiv gepackt und auf meinen Webspace geschmissen: http://w3.norman-interactive.com/files/Infect_Scope.lha

Besonders interssant ist in diesem Zusammenhang das Programm scopext2.
Es macht in Echtzeit eine Spektralanalyse der Daten vom Parallelportsampler. Mit meinem "Stereo Master" funktioniert das prima - dürfte vermutlich auch mit anderen Samplern funktionieren.

Doch vorsicht: Die Programme öffnen einen Pal-Screen. Und beim Beenden schmieren sie leider (zumindest bei mir) ab. :(

Wie genau die Spektralanalyse hier ist, kann ich nicht sagen.
Ist auch leider kein Sourcecode dabei, aber dafür ausführliche Textdateien.
--
http://www.norman-interactive.com

[ Dieser Beitrag wurde von Mad_Dog am 02.09.2006 um 18:45 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2006-09-02, 21:15 h

DaxB
Posts: 1422
User
Zitat:
Original von Mad_Dog:
Besonders interssant ist in diesem Zusammenhang das Programm scopext2.
Es macht in Echtzeit eine Spektralanalyse der Daten vom Parallelportsampler. Mit meinem "Stereo Master" funktioniert das prima - dürfte vermutlich auch mit anderen Samplern funktionieren.

Doch vorsicht: Die Programme öffnen einen Pal-Screen. Und beim Beenden schmieren sie leider (zumindest bei mir) ab. :(

Wie genau die Spektralanalyse hier ist, kann ich nicht sagen.
Ist auch leider kein Sourcecode dabei, aber dafür ausführliche Textdateien.

Scopext4 habe ich hier, incl. Sourcecode! Author: Smack/Infect! (Michael Henke). Da hier auch ein MuForce Hit beim beenden auftritt, hatt eich Michael Henke einen Bugreport geschickt. Leider (so weit ich mich noch erinnern kann) hat er keine Hardware oder Interesse.

Wer den Sourcecode haben will soll eben bescheid geben. Wäre auch schön, wenn jemand dann gleich den Bug beheben könnte. :)
Scopext4 rulet einfach nur. Hier mit dem TechnoSoundTurbo2 Sampler.

Sorry for being offtopic.

[ - Answer - Quote - Direct link - ]

2006-09-02, 22:39 h

MaikG
Posts: 5172
User
Was sind eigentlich 8000 HZ in Microsekunden?
Hab das Basic Programm soweit korregiert und eine Timer
Delay Funktion gefunden und eingefügt aber da es nichts
macht wird die Samplingrate falsch sein also 750 <> 8000HZ?

Das Programm guck ich mir mal an, aber wenn das keine CLI Ausgabe
macht wird das nicht viel nützen.

[ - Answer - Quote - Direct link - ]

2006-09-02, 23:59 h

DariusBrewka
Posts: 899
[Banned user]
Zitat:
Original von MaikG:
Was sind eigentlich 8000 HZ in Microsekunden?


Das ist aber eine komische Frage, ich kann dir höchstens sagen wie lange eine Schwingung dauert die du mit 8KHz abspielst, aber nicht was 8KHz in microsekunden sind. Wenn es das ist, was du wissen willst, dann ist die Antwort 1*10^6 / 8000

[ - Answer - Quote - Direct link - ]

2006-09-03, 10:33 h

MaikG
Posts: 5172
User
>Das ist aber eine komische Frage, ich kann dir höchstens sagen wie
>lange eine Schwingung dauert die du mit 8KHz abspielst, aber nicht
>was 8KHz in microsekunden sind. Wenn es das ist, was du wissen
>willst, dann ist die Antwort 1*10^6 / 8000

hä?

Wenn ich das mache:

1
warte x microsekunden
lese 1 Byte vom Parallelport
gehe zu DTMF auswertung
gehe zu 1


Wie gross ist x wenn ich 8000 HZ samplen will?


Also so muss ich das dem Unterprogramm übergeben:
POKEL VARPTR(currentval(0)) + tv_secs, 0
POKEL VARPTR(currentval(0)) + tv_micro, 008000 REM 500000=0.5s
junk = time_delay(VARPTR(currentval(0)), UNIT_MICROHZ&)

[ - Answer - Quote - Direct link - ]

2006-09-03, 11:34 h

bubblebobble
Posts: 707
User
@MaikG

125

--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Answer - Quote - Direct link - ]

2006-09-03, 15:08 h

MaikG
Posts: 5172
User
Funktioniert nicht :-(

Hab das korregierte Programm oben nochmal eingefügt.

[ - Answer - Quote - Direct link - ]

2006-09-03, 20:20 h

Holger
Posts: 8116
User
Zitat:
Original von MaikG:
>In C fangen Indizes immer mit 0 an, wenn die Größe 8 ist, gehen die
>gültigen Indizes von 0-7.

#define MAX_BINS 8

double q1[ MAX_BINS ];


Heiss doch aber dim q1#(8), also hat man ein 9er Array erstellt
q1#(0) bis q1#(8) besitzen gültigkeit. Also 1 ist da irgendwie
überflüssig.

Ich habe Dir gesagt, wie arrays in C funktionieren. Eine Größe von 8 bedeutet die Indizes 0-7 sind gültig, q1[8] ist nicht gültig. Die Zahlen 0, 1, 2, 3, 4, 5, 6, 7 sind 8 Zahlen. Punkt.
Zitat:
Also ich soll 8000 Mal(ob das Basic schafft?) einen Integer
wert übergeben also 0-255?

8000 Mal pro Sekunde ist langsam. Das sollte Basic hinbekommen. Wenn Du mit Basic vom Parallelport samplen willst, musst Du es ja auch hinbekommen.

Da der source-code nicht speziell für den Amiga geschrieben wurde, wird er wohl mit Standard-Samplingwerten arbeiten, wie man sie von Soundkarten oder CD bekommt. Also 16 Bit, zwischen -32768 und +32767. Aber der Algorithmus ist ziemlich robust und produziert auch mit falschen Bereichen erstaunlich gute Ergebnisse...
Zitat:
Wie soll man aus einer einzelnen Amplitude dann irgendeine Frequenz rausbekommen oder wird die irgendwo zwischengespeichert?
Der Goertzel-Algorithmus macht alles. Dass es globale Variablen gibt, hast Du doch schon selber bemerkt.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2006-09-03, 21:13 h

MaikG
Posts: 5172
User
>Ich habe Dir gesagt, wie arrays in C funktionieren. Eine Größe
>von 8 bedeutet die Indizes 0-7 sind gültig, q1[8] ist nicht gültig.
>Die Zahlen 0, 1, 2, 3, 4, 5, 6, 7 sind 8 Zahlen. Punkt.

Ist ja okay, in Basic müsste ich dann Dim x(7) schreiben, wenns
eins mehr ist macht das aber auch nichts.

>Da der source-code nicht speziell für den Amiga geschrieben wurde,
>wird er wohl mit Standard-Samplingwerten arbeiten, wie man sie von
>Soundkarten oder CD bekommt. Also 16 Bit, zwischen -32768 und +32767.
>Aber der Algorithmus ist ziemlich robust und produziert auch mit
>falschen Bereichen erstaunlich gute Ergebnisse...

Okay dann werde ich das nochmal ändern und es nochmal Probieren
mit 8 Bit gehts auf jeden fall nicht.

[ - Answer - Quote - Direct link - ]

2006-09-03, 23:01 h

MaikG
Posts: 5172
User
Hab noch ein bisschen was korregiert, das eine Subprogramm wurde
nicht angesprungen (auch im C Beispiel nicht), eine Schleife =4 statt =0.
Zeigt zwar schonmal irgendwas an, aber auch ohne das ich eine
Taste gedrückt habe oder eine falsche Ziffer oder gar keine, selten
die richtige.


Für 8->16 Bit hab ich folgenden code genommen, mit 8 Bit ist das
Ergebniss ähnlich:


sa%=PEEKB(&hBFE101)
IF sa%>127 THEN
sa%=sa%*128
ELSEIF sa%<127 THEN sa%=sa%*(-128)
ELSE sa%=0
END IF
bla%=goertzek%(sa%)

[ - Answer - Quote - Direct link - ]

2006-09-03, 23:30 h

DariusBrewka
Posts: 899
[Banned user]
Zitat:
Original von MaikG:
IF sa%>127 THEN
sa%=sa%*128
ELSEIF sa%<127 THEN sa%=sa%*(-128)
ELSE sa%=0
END IF


Was ist das für eine 8->16 Bit Umrechnung?

Ich vermute mal sa% steht für eine Vorzeichenbehaftete 16 Bit Variable, dann würde, so vermute ich mal, sa%=PEEKB(xyz) den entsprechenden Wert nach 16 Bit Vorzeichenbehaftet konvertieren. Wenn du jetzt Normieren willst mußt du den Wert einfach nur mit 256 muliplizieren.


Außerdem würde Ich dir Empfehlen zuerst zu Testen ob deine Funktion auch 8000/sek aufgerufen werden kann, sonst stimmts hinten und vorne Nicht, ansonsten erst GOERTZEL_N Werte vom Sampler lesen in ein Array und dann erst den Algorithmus anwenden. Du mußt Sicherstellen, daß die Bytes in konstanten Zeitabschnitten gelesen werden.

[ Dieser Beitrag wurde von DariusBrewka am 03.09.2006 um 23:41 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2006-09-04, 09:46 h

MaikG
Posts: 5172
User
>Was ist das für eine 8->16 Bit Umrechnung?

Meine eigene :-)

>Ich vermute mal sa% steht für eine Vorzeichenbehaftete 16 Bit
>Variable, dann würde, so vermute ich mal, sa%=PEEKB(xyz) den
>entsprechenden Wert nach 16 Bit Vorzeichenbehaftet konvertieren.
>Wenn du jetzt Normieren willst mußt du den Wert einfach nur mit 256
>muliplizieren.

sa% ist Integer, lege ich PEEKB(xyz) da rein ist sa% eine
zahl von 0-255, 127 ist dabei die 0.
Die Konventerierung erzeugt eine reguläre 0, und das Vorzeichen
und 16 Bit werte in akteptabler Amplitude.

>Außerdem würde Ich dir Empfehlen zuerst zu Testen ob deine Funktion
>auch 8000/sek aufgerufen werden kann, sonst stimmts hinten und
>vorne Nicht, ansonsten erst GOERTZEL_N Werte vom Sampler lesen in
>ein Array und dann erst den Algorithmus anwenden. Du mußt
>Sicherstellen, daß die Bytes in konstanten Zeitabschnitten gelesen
>werden.

Mh, muss ich mal gucken wie ich das mache. Aber da ja Fantasiewerte
angezeigt werden, denke ich da läuft was anderes schief.

[ - Answer - Quote - Direct link - ]

2006-09-04, 11:11 h

DariusBrewka
Posts: 899
[Banned user]
Zitat:
Original von MaikG:
sa% ist Integer, lege ich PEEKB(xyz) da rein ist sa% eine
zahl von 0-255, 127 ist dabei die 0.
Die Konventerierung erzeugt eine reguläre 0, und das Vorzeichen
und 16 Bit werte in akteptabler Amplitude.


Eine Kunvertierung muss sicherlich mehr als nur eine 0 Richtig konvertieren, alleine Schon an einer 1 und -1 kann man zeigen dass deine Konvertierung daneben liegt.

sa% = 255 = 0xff

da sa% > 127 -> sa% = sa% *128 -> sa% = 32640 , also positiv entgegten dem Eingangswert von 0xff welcher -1 entspricht.

sa% = 1 = 0x01

da sa% < 127 -> sa% = sa% * (-128) -> sa% = -128, also negativ entgegen dem Eingangswert von 0x01 welcher +1 entspricht.

Nun wäre es nicht weiter Problematisch wenn nur die Welle an der Zeitachse gespiegelt wäre, nein es sind auch die Werte total unterschiedlich und das nicht nur Faktoriell.

Ich will dir zuerst mal empfehlen dich mit der Darstellung von Zahlen auseinanderzusetzen, d.h. wie positive und negative Zahlen dargestellt werden, dann müsstest du auch eine Richtige Konversation hinbekommen auch wenn ich glaube das es dafür auch in Basic funktionen für geben muß.

Nachtrag:

Habe gerade gesehen dass deine Eingangsamplitude nur Verschoben ist, wenn das so ist mußt du einfach von sa% 127 abziehen und sa% dann negieren, die Amplitude anpassen indem du dann sa% mit 256 multiplizieren.
geändert. ]

[ Dieser Beitrag wurde von DariusBrewka am 04.09.2006 um 11:26 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2006-09-04, 11:32 h

Mad_Dog
Posts: 1944
User
Zitat:
Original von MaikG:
Was sind eigentlich 8000 HZ in Microsekunden?


Im Physikunterricht gepennt? ;)

1 Hz = 1/s

T = 1/n (T = Periodendauer, n = Frequenz)

1 Hz bedeutet "ein mal pro Sekunde".
D.h. wenn Du was 8000 mal pro Sekunde machen willst und dich fragst, wie lange "ein Durchgang" dauert, dann benutzt Du die Formel

T = 1/n

hier:

T = 1/8000
T = 0,000125 s

Siehe auch http://de.wikipedia.org/wiki/Frequenz

Zum Thema "milli, mikro, nano usw." : http://de.wikipedia.org/wiki/Vors%C3%A4tze_f%C3%BCr_Ma%C3%9Feinheiten

1 Millisekunde = 1 * 10 ^ -3 s
1 Mikrosekunde = 1 * 10 ^ -6 s

Also

0,000125 s
= 125 * 10 ^ -6 s
= 125 Mikrosekunden


--
http://www.norman-interactive.com

[ Dieser Beitrag wurde von Mad_Dog am 04.09.2006 um 11:37 Uhr geändert. ]

[ - Answer - Quote - Direct link - ]

2006-09-04, 11:50 h

MaikG
Posts: 5172
User
>Im Physikunterricht gepennt?

Nein, da hatte ich eine 1.

Tja, aber wie auch immer auf meinem 060er mit 60 MHZ werden
8000 HZ alle 10 sekunden erreicht, alle 3 Sekunden ohne
das "Delay".
Mit ein paar Optimierungen und Compileroptionen komme ich
auf etwa 1x pro sekunde, allerdings ohne delay(Trotzdem
Fantasieergebnisse).

Da das Zielsystem ein 030@50MHZ ist, nehme ich an das alles
umsonst war.
Selbst wenn ich die Samples in ein Array packen würde, würde
die Verarbeitung einiges an Zeit benötigen. Wenn ich z.B. ein
Passwort eingebe, wie ichs normalerweise mache währe auf einem
030er die erste Ziffer erst Decodiert wenn ich die 4. Eingegeben
hätte. Das Problem ist ziffern 2-4 wurden nicht gespeichert.

[ - Answer - Quote - Direct link - ]


1 2 -3- 4 5 6 7 8 Last [ - 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.
.