amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > DTMF erkennung in C [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

17.10.2006, 21:25 Uhr

MaikG
Posts: 5172
Nutzer
So nun habe ich es nach sehr langer Zeit geschafft ein C Programm
zusammenzustellen was DTMF erkennen soll.
Tja, das war scheinbar alles umsonst, weil dieses Programm macht
das selbe wie das MaxonBasic Programm.

20 Sekunden sind 23 Echtzeit Sekunden. Daher wird natürlich nichts
richtig erkannt.
Selbst bei Compilierung für 060 sind es 23 Sekunden.
Ergo es liegt nicht an MaxonBasic!

Aber da es jetzt schon in C geschrieben ist vielleicht weiss
ja jemand warum das Timing so viel Zeit verbraucht.
Oder jemand hat eine Routine die direkt auf die CIA-Timer zugreifen?

code:
#include <clib/alib_protos.h>
    #include <clib/exec_protos.h>

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h> 
    #include <exec/exec.h>
    #include <exec/ports.h>
    #include <exec/libraries.h>
    #include <exec/io.h>
    #include <dos/dos.h>

    #include <proto/dos.h>
    #include <proto/exec.h>
    #include <proto/timer.h>
    #include <devices/timer.h>
    #include <stdint.h>
    #include <math.h>

    struct timerequest *TimerIO;
    struct MsgPort *TimerMP;
    struct Message *TimerMsg;
    struct Library *TimerBase;

#define SAMPLING_RATE       8000
#define MAX_BINS            8
#define GOERTZEL_N          92

int    sample_count;
double q1[ MAX_BINS ];
double q2[ MAX_BINS ];
double r[ MAX_BINS ];

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

double      coefs[ MAX_BINS ] ;


void
post_testing()
{
int         row, col, see_digit;
int         peak_count, max_index;
double      maxval, t;
int         i;
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;
        }
    }

    /* 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;
        }
    }


    /* 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[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[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 n", row_col_ascii_codes[row][col-4]);
        }
    }
}

void
goertzel( int sample )
{
double      q0;
int        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;
    }
}


int main(void)
{
int n;
         ULONG Loops;
         Loops=160000;
         struct timeval ref1, ref2;
        struct EClockVal eclockval;
        unsigned long intervall, ticks;
        long diff;
        LONG error;

        unsigned int repeat = 0;

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

        memset((void *)0xBFE301,0x0,1);

        TimerMP = (struct MsgPort *)CreatePort(NULL, 0);
        if(!TimerMP)
        {
            Printf("Konnte Timer-Port nicht anlegen!n");
            exit(RETURN_FAIL);
        }

        TimerIO = (struct timerequest *)CreateExtIO(TimerMP, sizeof(struct timerequest));
        if(!TimerIO)
        {
            Printf("Konnte Timer-IORequest nicht anlegen!n");
            exit(RETURN_FAIL);
        }

        error = OpenDevice(TIMERNAME, UNIT_WAITECLOCK, (struct IORequest *)TimerIO, 0L);
        if(error)
        {
            Printf("Konnte timer.device nicht öffnen!n");
            exit(RETURN_FAIL);
        }
        
        TimerBase = (struct Library *)TimerIO->tr_node.io_Device;

        Printf("Gewünschtes Intervall in Hz: n ");
        scanf("%lu", &intervall);

        ticks = ReadEClock(&eclockval);
        diff = ticks / intervall; /* Normal müßte man auf - testen */

/*        Printf("Hi: %lu Lo: %lun", eclockval.ev_hi, eclockval.ev_lo); */

        /* sehr simpler Überlauf-Test */
        if( ((eclockval.ev_lo) + diff) < eclockval.ev_lo)
        {
            eclockval.ev_hi++;
        }
        else
        {
            eclockval.ev_lo += diff;
        }

/*        //printf("New Hi: %lu New Lo: %lun", eclockval.ev_hi, eclockval.ev_lo); */

        TimerIO->tr_node.io_Command = TR_ADDREQUEST;
        TimerIO->tr_time.tv_secs = eclockval.ev_hi;
        TimerIO->tr_time.tv_micro = eclockval.ev_lo;

        SendIO((struct IORequest *)TimerIO);

        GetSysTime(&ref1);

        while(repeat < Loops)
        {
            TimerMsg = WaitPort(TimerMP);
            
            /* Vorsicht, wilde Überläufe ;)  */
            if( ((eclockval.ev_lo) + diff) < eclockval.ev_lo)
            {
                eclockval.ev_hi++;
            }
            else
            {
                eclockval.ev_lo += diff;
            }
            TimerIO->tr_node.io_Command = TR_ADDREQUEST;
            TimerIO->tr_time.tv_secs = eclockval.ev_hi;
            TimerIO->tr_time.tv_micro = eclockval.ev_lo;
            SendIO((struct IORequest *)TimerIO);
            /* hier was sinnvolles tun, sofern vorhanden */

        volatile uint8_t *parallel=(uint8_t*)0xBFE101;
        signed int sample=*parallel;
        goertzel((sample-127)<<8);

            repeat++;
        }    

        GetSysTime(&ref2);

        AbortIO((struct IORequest *)TimerIO);
        WaitIO((struct IORequest *)TimerIO);    

        CloseDevice((struct IORequest *)TimerIO);
        DeleteExtIO((struct IORequest *)TimerIO);
        DeletePort(TimerMP);

        Printf("n");
        Printf("Intervall(EClock-ticks): %ldn", ticks / intervall);
        Printf("Referenz 1: %ld %ldn", ref1.tv_secs, ref1.tv_micro);
        Printf("Referenz 2: %ld %ldn", ref2.tv_secs, ref2.tv_micro);
        SubTime(&ref2, &ref1);
        Printf("Differenz:  %9ld %ldn", ref2.tv_secs, ref2.tv_micro);
        
        exit(RETURN_OK);

}


[ - Antworten - Zitieren - Direktlink - ]

17.10.2006, 22:30 Uhr

bubblebobble
Posts: 707
Nutzer
Also im Falle eines Überlaufen musst du nicht nur
den HI Wert hochzählen, sondern auch den LOW Wert,
sonst kannst du eine sehr lange Kaffepause einlegen gehen ...

Anstatt
while(repeat < Loops)

würde ich auf
while (SIGBREAKF_CTRL_C&SetSignal(0,SIGBREAKF_CTRL_C)==0)

testen, dann kannst du mit CTR+C abbrechen anstatt immer fix zu warten.


Wenn du 23 statt 20 secs brauchst, ist das schon ok glaube ich.
Wie schnell ist es, wenn du das WaitPort und das sendIO weg lässt ?


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


[ - Antworten - Zitieren - Direktlink - ]

17.10.2006, 22:34 Uhr

thomas
Posts: 7718
Nutzer
@MaikG:

Zitat:
code:
/* Vorsicht, wilde Überläufe   */
            if( ((eclockval.ev_lo) + diff) < eclockval.ev_lo)
            {
                eclockval.ev_hi++;
            }
            else
            {
                eclockval.ev_lo += diff;
            }



Wild ist gar kein Ausdruck. Überleg dir mal, was dieser Abschnitt macht, wenn ein Überlauf stattfindet. Und vor allem, was beim nächsten Durchlauf nach einem Überlauf passiert. Bei dir kommt nach dem ersten Überlauf nämlich immer ein Überlauf, weil du das Kriterium, an dem du den Überlauf erkennst, gar nicht veränderst.

Richtig müßte es heißen:

code:
old_ev_lo = eclockval.ev_lo;
eclockval.ev_lo += diff;
if (eclockval.ev_lo < old_ev_lo)
    eclockval.ev_hi ++;


Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

17.10.2006, 22:52 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von thomas:
@MaikG:

Wild ist gar kein Ausdruck. Überleg dir mal, was dieser Abschnitt macht, wenn ein Überlauf stattfindet. Und vor allem, was beim nächsten Durchlauf nach einem Überlauf passiert. Bei dir kommt nach dem ersten Überlauf nämlich immer ein Überlauf, weil du das Kriterium, an dem du den Überlauf erkennst, gar nicht veränderst.

Richtig müßte es heißen:

code:
old_ev_lo = eclockval.ev_lo;
eclockval.ev_lo += diff;
if (eclockval.ev_lo < old_ev_lo)
    eclockval.ev_hi ++;



Das hat er aus meinem Beispiel aus einem anderen Thread, das ich auf die Schnelle zusammengehackt hatte. Mir ist da der Fehler unterlaufen, die Bewertungsstrategie von Cobol mit der von C zu vertauschen, daher danke für die Korrektur.

Trotzdem raff ich nicht, weshalb bei ihm nahezu das gleiche Programm ständig länger läuft als bei mir...

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

17.10.2006, 23:22 Uhr

MaikG
Posts: 5172
Nutzer
> old_ev_lo = eclockval.ev_lo;
> eclockval.ev_lo += diff;
> if (eclockval.ev_lo < old_ev_lo)
> eclockval.ev_hi ++;


Okay hab ich 2x so eingefügt und old_ev_lo als LONG definiert.
Jetzt dauerts noch länger 27 Sekunden.


>Trotzdem raff ich nicht, weshalb bei ihm nahezu das gleiche
>Programm ständig länger läuft als bei mir...

Weil keiner bissher einen Timing Code inklusive DTMF ausprobiert
hat. Timing lief unter Basic auch schon korrekt, görtzel rannte
nur so durch aber beides zusammen geht ebend nicht.


>Wenn du 23 statt 20 secs brauchst, ist das schon ok glaube ich.

Das ist für Goerzel alswenn man eine Kassette zu schnell abspielt
so funktioniert das nicht.

>Wie schnell ist es, wenn du das WaitPort und das sendIO weg lässt ?

6 Sekunden also ist es wie bei Basic, wenig Zeit wird für goertzel
benötig viel für das Timing.

[ Dieser Beitrag wurde von MaikG am 17.10.2006 um 23:28 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.10.2006, 23:34 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
> old_ev_lo = eclockval.ev_lo;
> eclockval.ev_lo += diff;
> if (eclockval.ev_lo < old_ev_lo)
> eclockval.ev_hi ++;


Okay hab ich 2x so eingefügt und old_ev_lo als LONG definiert.
Jetzt dauerts noch länger 27 Sekunden.


Äh... was?? Das wären ja 4 Sekunden mehr. So viele Zyklen verballert eine Zuweisung mehr nun auch wieder nicht. Das Programm muß ich mir mal in Ruhe ansehen bzw. mein eigenes hervorkramen und mit der CIA-Mimik versehen. Dann halt ohne Sampler dran.

Zitat:
>Trotzdem raff ich nicht, weshalb bei ihm nahezu das gleiche
>Programm ständig länger läuft als bei mir...

Weil keiner bissher einen Timing Code inklusive DTMF ausprobiert
hat. Timing lief unter Basic auch schon korrekt, görtzel rannte
nur so durch aber beides zusammen geht ebend nicht.


Na, eben doch. Das hatte ich in dem ersten Thread auch geschrieben. Da habe ich nichts anderes gemacht wie Du, den goertzel einfach platt reinkopiert. Hier bei mir lief das auch ordentlich, sogar auf dem 4000er.

Deswegen wundere ich mich ja so, daß das bei Dir immer im Bereich von mehreren Sekunden langsamer läuft, sobald Du da Timing einsetzt, egal ob MB oder C. Zeit genug ist zwischen den SendIO() bei 8000Hz auf jeden Fall, würde mich arg wundern, wenn das Timing nur bei mir ordentlich läuft. Noch dazu auf WinUAE und 4000er nahezu gleich.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

17.10.2006, 23:39 Uhr

bubblebobble
Posts: 707
Nutzer
... und wie schnell ist es, wenn du den Görzel weglässt ?
Wenn es immer noch 23 ist, dann ist das die Ungenauigkeit des Timers.

Klar, das ist als wenn du die Kasette zu schnell abspielst.
Evtl. gehe mit der Samplingrate runter, dann sollte es klappen, wenn es wirklich daran liegt, dass das Program zu lange braucht.

Achja, das kannst du auch so messen:

Baue das SIGBREAKF_CTRL_C ein, damit es lange ganu laufen kann.
Dann starte das Program, und schaue mit einem CPU Monitor was passiert.
Wenn dein programm 100% CPU Last fährt, dann ist es wirklich zu langsam.
Wenn du noch 75% oder mehr frei hast, dann liegt es garantiert nicht an dem zu langsamen Programm, sondern dann ist der timer einfach zu ungenau.

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


[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 00:10 Uhr

whose
Posts: 2156
Nutzer
@bubblebobble:

Der Gag bei der Geschichte ist ja, daß er das bereits einmal als Programm in MaxonBASIC implementiert hatte. Da gabs diese Mehrlaufzeiten auch ohne Goertzel.

Ich hatte dann das C-Programm mit UNIT_WAITECLOCK aufgesetzt, da läuft das Timing ordentlich, sogar in der BASIC-Fassung. Die Ungenauigkeiten des Timers kamen da auch mehr von der UNIT_MICROHZ bzw. GetSysTime(), die zum Messen benutzt wurden und etwas ungeschickt angelegter Start- und Endpunkte für die Messung meinerseits. Das Verhalten des Programms in Bezug auf die Timer-Ungenauigkeiten war aber ok, selbst über 30 Sekunden Dauer.

Später hatte ich dann mal den Goertzel eingesetzt, auf den Holger per Link verwiesen hatte, das Timing blieb weiterhin in den Grenzen wie ohne Goertzel, bei Maik allerdings nicht. Sobald der den Goertzel in seinem BASIC-Programm aktivierte, riß das Teil aus.

Und jetzt halt schon wieder, nur diesmal in C. Und das raffe ich einfach im Moment nicht. Die letzte Möglichkeit, die sich mir noch anbietet, wäre, tatsächlich auf Ungenauigkeiten bei der Referenzmessung zu tippen. Ist ja nicht soooo arg unwahrscheinlich. Dann hätte die ganze Diskussion hier aber keinen Wert, weil er halt nur meint, es würde "falsch" laufen.

Da müßte man dann evtl. mal die aufgenommenen Samples sehen und das Originalsignal dazu, um die Korrektheit des Sample-Timings einwandfrei überprüfen zu können.

Schwierige Kiste irgendwie...

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 10:08 Uhr

MaikG
Posts: 5172
Nutzer
>Das Programm muß ich mir mal in Ruhe ansehen bzw. mein eigenes
>hervorkramen und mit der CIA-Mimik versehen. Dann halt ohne Sampler
>dran.

Das währe schön, ohne Sampler macht nichts, bekommst du halt
immer 127 oder so.

>Na, eben doch. Das hatte ich in dem ersten Thread auch geschrieben.
>Da habe ich nichts anderes gemacht wie Du, den goertzel einfach
>platt reinkopiert. Hier bei mir lief das auch ordentlich, sogar auf
>dem 4000er.

Mh, ich hab einen 060@60MHZ.

>... und wie schnell ist es, wenn du den Görzel weglässt ?

20 Sekunden :

Intervall(EClock-ticks): 88
Referenz 1: 908704434 564510
Referenz 2: 908704455 491133
Differenz: 20 926623

wie beim Basic programm ohne goertzel okay.

>Evtl. gehe mit der Samplingrate runter, dann sollte es klappen,
>wenn es wirklich daran liegt, dass das Program zu lange braucht.

Wie schon gesagt das muss auf 030@50MHZ laufen und der ist
nicht halb so schnell wie ein 060er.

Achja, das kannst du auch so messen:

>Dann starte das Program, und schaue mit einem CPU Monitor was
>passiert.

Dopus zeigt 100%


>Die Ungenauigkeiten des Timers kamen da auch mehr von der
>UNIT_MICROHZ bzw. GetSysTime(), die zum Messen benutzt
>wurden und etwas ungeschickt angelegter Start- und Endpunkte
>für die Messung meinerseits. Das Verhalten des Programms in
>Bezug auf die Timer-Ungenauigkeiten war aber ok, selbst über
>30 Sekunden Dauer.

>Und jetzt halt schon wieder, nur diesmal in C. Und das raffe ich
>einfach im Moment nicht. Die letzte Möglichkeit, die sich mir noch
>anbietet, wäre, tatsächlich auf Ungenauigkeiten bei der
>Referenzmessung zu tippen. Ist ja nicht soooo arg unwahrscheinlich.

Da die Computerreferenzmessung mit meiner Stopuhr übereinstimmt
und ich nicht 3 bzw. 7 Sekunde reaktionszeit habe stimmt diese
Zeit.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 14:31 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
> old_ev_lo = eclockval.ev_lo;
> eclockval.ev_lo += diff;
> if (eclockval.ev_lo < old_ev_lo)
> eclockval.ev_hi ++;


Okay hab ich 2x so eingefügt und old_ev_lo als LONG definiert.
Jetzt dauerts noch länger 27 Sekunden.


Die Mühe versteh ich nicht. In dem Programm steht immer noch #include <stdint.h>, d.h. Du übersetzt mit einem C99-fähigen compiler. Da kannst Du, ohne drüber nachdenken zu müssen, 64-Bit Arithmetik benutzen, und wie der Code dafür aussehen muss, weißt Du ja. Der steht in dem anderen Programm.

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

[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 18:22 Uhr

MaikG
Posts: 5172
Nutzer
>Da kannst Du, ohne drüber nachdenken zu müssen, 64-Bit Arithmetik
>benutzen, und wie der Code dafür aussehen muss, weißt Du ja. Der
>steht in dem anderen Programm.

Ich verstehe nicht viel von C, das müsstest du genauer erklären.
Ich soll für irgendwas eine Variable nehmen die Doppelt so lang
ist wie eine Long?

[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 18:46 Uhr

bubblebobble
Posts: 707
Nutzer
@Maik:

Sieht so aus, als ob das ganze einfach zu lahm ist.
Probier mal GCC, evtl. ist der schneller.
Oder Amiblitz2 ;-)

Ansonsten gehts halt nicht.

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


[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 19:53 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Ich verstehe nicht viel von C, das müsstest du genauer erklären.
Ich soll für irgendwas eine Variable nehmen die Doppelt so lang
ist wie eine Long?


Doppelt so lang klingt etwas schräg. Eine Variable, die doppelt so genau ist.

So wie in diesem Beispielcode benutzt:
http://amiga-news.de/forum/thread.php?id=23479&start=211&BoardID=7#241727

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

[ - Antworten - Zitieren - Direktlink - ]

18.10.2006, 23:19 Uhr

MaikG
Posts: 5172
Nutzer
>Sieht so aus, als ob das ganze einfach zu lahm ist.

Goertzel alleine läuft in 6 Sekunden durch, das ein Timing
mehr als das doppelte dauern kann, kann mir keiner erzählen.

>Probier mal GCC, evtl. ist der schneller.

Und dann wandle ich das Programm in Pascal und es macht das
selbe...
Wenns mit 000 Opt genauso schnell ist wie 060 Opt, scheint
sowas eine untergeordnete rolle zu spielen.


>Doppelt so lang klingt etwas schräg. Eine Variable, die doppelt so
>genau ist.

Verstehe ich nicht dafür gibts doch dann double(# in Basic).

>So wie in diesem Beispielcode benutzt:
>http://amiga-news.de/forum/thread.php?id=23479&start=211&BoardID=7#241727

Ah, und da muss ich dann nichts mehr modifizieren?

Edit: hab das eingesetzt und bekomme nur Enforcer hits, wie bei
den einen schon vollständigen Programm.

[ Dieser Beitrag wurde von MaikG am 18.10.2006 um 23:47 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

19.10.2006, 12:54 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von MaikG:
>Da kannst Du, ohne drüber nachdenken zu müssen, 64-Bit Arithmetik
>benutzen, und wie der Code dafür aussehen muss, weißt Du ja. Der
>steht in dem anderen Programm.

Ich verstehe nicht viel von C, das müsstest du genauer erklären.
Ich soll für irgendwas eine Variable nehmen die Doppelt so lang
ist wie eine Long?


Guckst Du hier:

http://www.norman-interactive.com/C-Kurs_Datentypen.html

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

[ Dieser Beitrag wurde von Mad_Dog am 19.10.2006 um 12:55 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

19.10.2006, 13:12 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Mad_Dog:
Guckst Du hier:

http://www.norman-interactive.com/C-Kurs_Datentypen.html


Na ja, da stehen nur die alten C-Datentypen, deren Wertebereiche so, wie Du sie dort auflistest, für den Amiga zutreffend sein mögen, aber eben nicht eindeutig definiert sind.

Dafür gibt es eben die C99-Datentypen, wie long long [int] und die, die in stdint.h definiert werden. Also int8_t 1 Byte, int16_t 2 Bytes, int32_t 4 Bytes, int64_t 8 Bytes, uint8_t 1 Byte, uint16_t 2 Bytes, uint32_t 4 Bytes, uint64_t 8 Bytes.

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

[ - Antworten - Zitieren - Direktlink - ]

19.10.2006, 13:24 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
>Doppelt so lang klingt etwas schräg. Eine Variable, die doppelt so
>genau ist.

Verstehe ich nicht dafür gibts doch dann double(# in Basic).


Das deutsche Wort >doppelt< bedeutet so viel wie >zweifach< oder >zwei mal so viel<. Wenn ich also von einem doppelt so genauen integer-Datentyp spreche, dann meine ich wohl einen, der doppelt so genau ist, wie der integer-Datentyp, den Du sonst verwendest, in dem code offensichtlich "ULONG" oder "LONG".

Dass derjenige, der C verbrochen hat, durch erlaubte Weglassungen erzwungen hat, dass nun ein C-Programmierer wissen muss, dass nach long "offensichtlich" int weggelassen wurde, double dagegen float bedeutet, obwohl auch noch long float oder gar long double (== long long float?) durchgehen würden, sollte unseren deutschen Sprachgebrauch nicht beeinflussen.

Doppelt heißt auch weiterhin >zweifach< und nicht >Fließkomma< und abstrakte Dinge wie >Integerzahlen< haben keine Länge.

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

[ - Antworten - Zitieren - Direktlink - ]

19.10.2006, 15:04 Uhr

NoImag
Posts: 1050
Nutzer
Zitat:
Original von Holger:
Doppelt heißt auch weiterhin >zweifach< und nicht >Fließkomma< und abstrakte Dinge wie >Integerzahlen< haben keine Länge.


Das Wort "genau" im Zusammenhang mit ganzen Zahlen halte ich für genauso unglücklich. Außerdem können abstrakte Dinge wie Zahlen in ihrer konkreten Verwendung sehr wohl eine Länge haben. Bei ganzen Zahlen z.B. die Anzahl der Dezimalstellen oder meinetwegen auch die Anzahl der Binärstellen.

Tschüß


[ - Antworten - Zitieren - Direktlink - ]

19.10.2006, 15:11 Uhr

MaikG
Posts: 5172
Nutzer
>int32_t 4 Bytes,
>int64_t 8 Bytes,


Hatte ich das nicht gesagt?
Doppelt so lang wie long.

Ich glaube ich verstehe den Anwendungszweck bei Readeclock, low
und high gibts nur weil ein uhrsprünglich kein 64 Bit beim
Amiga gab. Eigentlich gehören diese werte zusammen.

Wie auch immer, abstürzen tut es trotzdem.


>Doppelt heißt auch weiterhin >zweifach< und nicht >Fließkomma<
>und abstrakte Dinge wie >Integerzahlen< haben keine Länge.


Okay.

[ - Antworten - Zitieren - Direktlink - ]

19.10.2006, 19:14 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von NoImag:
Das Wort "genau" im Zusammenhang mit ganzen Zahlen halte ich für genauso unglücklich.

Wieso?
Genauigkeit ist nunmal relativ. Und ganze Zahlen besitzen deshalb auch eine Genauigkeit, die man vergleichen kann.
Und jeder von einem Computer verarbeitbarer Datentyp besitzt eine begrenzte Genauigkeit.
Zitat:
Außerdem können abstrakte Dinge wie Zahlen in ihrer konkreten Verwendung sehr wohl eine Länge haben. Bei ganzen Zahlen z.B. die Anzahl der Dezimalstellen oder meinetwegen auch die Anzahl der Binärstellen.
Oder Anzahl der Buchstaben in C, int ist kürzer als long, welches wiederum kürzer als double ist, wobei char allerdings länger als int ist. Oder Anzahl der Erwähnungen in einem Programmierhandbuch für Anfänger.

Irgendwie scheint es nicht wirklich sinnvoll zu sein, eine Anzahl als Länge zu bezeichnen, oder?

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

[ - Antworten - Zitieren - Direktlink - ]

20.10.2006, 00:13 Uhr

NoImag
Posts: 1050
Nutzer
Zitat:
Original von Holger:
Wieso?
Genauigkeit ist nunmal relativ. Und ganze Zahlen besitzen deshalb auch eine Genauigkeit, die man vergleichen kann.
Und jeder von einem Computer verarbeitbarer Datentyp besitzt eine begrenzte Genauigkeit.


Nein. Die Datentypen besitzen einen Zahlenbereich. Den Zahlenbereich als Genauigkeit zu bezeichnen, ist nicht besonders einleuchtend. Die Genauigkeit (so wie dieses Wort allgemein verstanden wird) ist bei allen Ganzzahltypen gleich. Unterschiedliche Genauigkeit (im allgemein verständlichen Sinne) gibt es nur bei Fließkommatypen.

Zitat:
Oder Anzahl der Buchstaben in C, int ist kürzer als long, welches wiederum kürzer als double ist, wobei char allerdings länger als int ist. Oder Anzahl der Erwähnungen in einem Programmierhandbuch für Anfänger.

Irgendwie scheint es nicht wirklich sinnvoll zu sein, eine Anzahl als Länge zu bezeichnen, oder?


Willst Du Dich jetzt absichtlich dumm stellen? Die Anzahl der Stellen einer Zahl bei ihrer Darstellung gibt an wieviel Platz die Zahl benötigt. Platz ist aber etwas räumliches und somit machen Begriffe wie Länge Sinn. Natürlich könnte man auch von Höhe oder Breite sprechen, aber wenn etwas verkettet wird, wie bei der Darstellung einer Zahl, dann spricht man üblicherweise von Länge.

Tschüß


[ - Antworten - Zitieren - Direktlink - ]

21.10.2006, 18:11 Uhr

MaikG
Posts: 5172
Nutzer
Ist ja egal wie man das jetzt mit der 64Bit Variable auch immer
ausdrückt ich weiss was gemeint ist, können wir zurück zum Uhrsprünglichen
Thema kommen?

[ - Antworten - Zitieren - Direktlink - ]

26.10.2006, 16:26 Uhr

MaikG
Posts: 5172
Nutzer
Ich habs jetzt nochmal unter WinUAE ausprobiert um ein Problem
mit dem System 100% auszuschliessen.

WinUAE benötigt 31 Sekunden also nochmal wesentlich länger.

(AMD500MHZ,128MB,Voodoo3, WinUAE JIT 8MB, Sound aus, OCS, Picasso96)

[ - Antworten - Zitieren - Direktlink - ]

26.10.2006, 21:25 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
>So wie in diesem Beispielcode benutzt:
>http://amiga-news.de/forum/thread.php?id=23479&start=211&BoardID=7#241727

Ah, und da muss ich dann nichts mehr modifizieren?

Edit: hab das eingesetzt und bekomme nur Enforcer hits, wie bei
den einen schon vollständigen Programm.


Was für Hits? Enforce sagt doch bestimmt ein bisserl mehr, als nur "Hit".

Bei mir läuft's jedenfalls -- Du musst das Programm mit CTRL+C abbrechen, dann gibt es Dir an, wieviele Warteanforderungen bearbeitet wurden. So kann man es ziemlich einfach mit unterschiedlich langen Gesamtlaufzeiten testen.

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

[ - Antworten - Zitieren - Direktlink - ]

27.10.2006, 08:46 Uhr

MaikG
Posts: 5172
Nutzer
>Was für Hits? Enforce sagt doch bestimmt ein bisserl mehr,
>als nur "Hit".


Ich glaub das sind die gleichen wie mit dem ganzen Programm aus
dem anderen Threat.


Name: "Background CLI" CLI: "a.out" Hunk 0000 Offset 0000035A
LONG-READ from 8878EC9A PC: 44658080
USP: 4465E2A4 SR: 0004 FLSW: 01010200 TCB: 44656B88
Data: 442BCF48 00003F88 00000000 00000001 00001000 0000000C 110AF379 44657D04
Addr: 4465E374 4465E370 4463A339 442BCF48 443CB61E 442BCF08 44000B40 4465E2A4
Stck: 0000FFFF 4463A339 00000000 44000B40 4465811E 00000014 4463A339 442BCE90
Stck: 44658192 00000014 4463A339 44656B88 44000B40 44657F42 00000001 442BCF18
Stck: 00000000 442BCF08 00F9FDEA 00004000 446576F4 00004028 442BCF2C 442BCF28
Stck: 0A0A00F8 23650000 4465E398 4465E320 44662320 00003F88 00000000 00000020
Stck: 00004000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Stck: 00000000 00000020 00003FD8 2030383A 34303A33 35000000 00000000 00000000
Stck: 00000000 00000000 00000000 00000020 00003FB0 00000000 00000000 00000000
Stck: 00000000 456E7466 65726E65 2067656C F6736368 00000000 00003F88 69636874
----> 44658080 - "a.out" Hunk 0000 Offset 00000378
----> $44658080: TST.L ($443c367c.L,A4)
----> 4465811E - "a.out" Hunk 0000 Offset 00000416
----> $4465811e: ADDQ.W #$4,A7
----> 442BCE90 - "a.out" Hunk 0003 Offset 00000000
----> $442bce90: ORI.B #$00,D0
----> 44658192 - "a.out" Hunk 0000 Offset 0000048A
----> $44658192: ADDQ.W #$4,A7
----> 44657F42 - "a.out" Hunk 0000 Offset 0000023A
----> $44657f42: MOVEQ #$00,D2
----> 00F9FDEA - "ROM - dos 40.3 (1.4.93)" Hunk 0000 Offset 00000B2E
----> $00f9fdea: MOVEM.L (A7)+,D2-D3
D0--> 442BCF48 - "a.out" Hunk 0004 Offset 00000000
----> $442bcf48: ORI.B #$00,D0
A3--> 442BCF48 - "a.out" Hunk 0004 Offset 00000000
----> $442bcf48: ORI.B #$00,D0
Name: "Background CLI" CLI: "a.out" Hunk 0000 Offset 00000378
LONG-READ from 8878EC46 PC: 4465809E
USP: 4465E2A4 SR: 0004 FLSW: 01010200 TCB: 44656B88
Data: 442BCF48 00003F88 00000000 00000001 00001000 0000000C 110AF379 44657D04
Addr: 4465E374 4465E370 4463A339 442BCF48 443CB61E 442BCF08 44000B40 4465E2A4
Stck: 0000FFFF 4463A339 00000000 44000B40 4465811E 00000014 4463A339 442BCE90
Stck: 44658192 00000014 4463A339 44656B88 44000B40 44657F42 00000001 442BCF18
Stck: 00000000 442BCF08 00F9FDEA 00004000 446576F4 00004028 442BCF2C 442BCF28
Stck: 0A0A00F8 23650000 4465E398 4465E320 44662320 00003F88 00000000 00000020
Stck: 00004000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Stck: 00000000 00000020 00003FD8 2030383A 34303A33 35000000 00000000 00000000
Stck: 00000000 00000000 00000000 00000020 00003FB0 00000000 00000000 00000000
Stck: 00000000 456E7466 65726E65 2067656C F6736368 00000000 00003F88 69636874
----> 4465809E - "a.out" Hunk 0000 Offset 00000396
----> $4465809e: TST.L ($443c3628.L,A4)
----> 4465811E - "a.out" Hunk 0000 Offset 00000416
----> $4465811e: ADDQ.W #$4,A7
----> 442BCE90 - "a.out" Hunk 0003 Offset 00000000
----> $442bce90: ORI.B #$00,D0
----> 44658192 - "a.out" Hunk 0000 Offset 0000048A
----> $44658192: ADDQ.W #$4,A7
----> 44657F42 - "a.out" Hunk 0000 Offset 0000023A
----> $44657f42: MOVEQ #$00,D2
----> 00F9FDEA - "ROM - dos 40.3 (1.4.93)" Hunk 0000 Offset 00000B2E
----> $00f9fdea: MOVEM.L (A7)+,D2-D3
D0--> 442BCF48 - "a.out" Hunk 0004 Offset 00000000
----> $442bcf48: ORI.B #$00,D0
A3--> 442BCF48 - "a.out" Hunk 0004 Offset 00000000
----> $442bcf48: ORI.B #$00,D0
Name: "Background CLI" CLI: "a.out" Hunk 0000 Offset 00000396


[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > DTMF erkennung in C [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.