Seite 4 von 9

Verfasst: Di 13. Jan 2004, 16:20
von schabbeskugel
@paepcke: Ja, sorry, aber ich hatte auch schon Mail von einen Benutzer, der sich darüber geärgert hat, weil ich die Sourcen veröffentlicht habe, weil er sowas vermarkten wollte.
Und das wegen einer "lächerlichen" DFT Hin- und Rücktransformation.
Das mit "besonders schützenswert" sehe ich eigentlich genauso.

Andererseits: Bisher habe ich kein solches Programm gefunden (oder vielleicht auch nicht intensiv genug gesucht).

---
Am Programm muß noch einiges verbessert werden: Fehlerprüfung, Wav-datei-Formatprüfung, und die Selektivität der Frequenzbereiche durch das Cosinus-Fenster habe ich auch noch nicht geprüft;
Ein Test mit Rosa rauschen hat allerdings gezeigt, daß das Programm doch gut das macht, was es sollte.

Für's Rosa rauschen (-10db/dekade) habe ich auch einen "Generator" gebastelt. Und natürlich auch das Progrämmelchen, das aus einer Wav-Datei das gemittelte Frequenzspektrum 'rausspuckt.
Stelle ich auf Wunsch auch noch 'rein.
---

Cool wäre auch, wenn das Programm den Bassbereich nach Basspegel dynamisch erweitert, d. h. bei kleinen Lautstärken bis 20Hz, bei großen vielleicht bis 40 oder so.
Es gibt aber zwei Haken: Erstens ist mir diese Materie noch nicht geläufig, außerdem weiß man nicht, mit welcher Lautstärke das ganze letzlich abgespielt wird. Das geht wohl nur mit einer digital-Aktivbox mit Lautstärkeregler.

Verfasst: Di 13. Jan 2004, 16:55
von Frank Klemm

Code: Alles auswählen

/*
 *   Restrictions:
 *   - can only handle 2x 16 bit data
 *   - many, many other
 *
 *   Ungetestet, Unvollständig, Unbedienbar, Quick&Dirty
 *   Ohne GPL-Header, dafür mit Kommentaren 
 *   (verbietet die GNU-Religion eigentlich Kommentare neben dem Vater-Unser im Header?)
 */

/*
 *   Design Guide
 *   ~~~~~~~~~~~~
 *   Der Filter ist ein sogenannter DFT-Filter mit Double Overlap. In der Literatur habe ich darüber noch nichts gefunden.
 *   DFT-Filter sind keine LTI-Systeme. Sie sind nicht TI, sind aber L. Um die NTI-Eigenschaft zu mildern, verwendet man
 *   überlappende Blocks und "fenstert" diese gewöhnlich vor der Analyse (damit die Funktion glatt wird und keine Stufen
 *   am Rand hat, was zu frequenzmäßigem Ausbluten führt) und nach der Re-Synthese (damit es keine Sprungstellen durch
 *   nicht perfekte Anschlußstellen kommt, die zu deutlichen Knacksern führen. Typischerweise nimmt man für beide Fenste-
 *   rungen die gleiche Funktion. Damit keine Seitenbänder auftreten, müssen die Fenster perfekt wieder zusammensetzbar sein.
 *   Bei Single Overlap führt das zur Forderung, daß w1^2 + w2^2 = 1 sein muß, bei Double Overlap zu w1^2 + w2^2 + w3^2 = 1.
 *   Single Overlap stellt die gleichen Forderungen der MDCT, daher sind auch die dort üblichen Fensterfunktionen verwendbar
 *   (Sinus, KBD, CosSin). Double Overlap stellt andere Forderungen, u.a. geht sehr gut das Sinus^2-Fenster, was sehr gute
 *   Eigenschaften aufweist. Nachteilig ist eine DFT der Breite 3*2^n, die nicht so schnell mal hingekritzelt ist.
 *
 *   Der Kern des Programms (neben dem garstigen Zeug, was immer noch rundherum erledigt werden muß) besteht darin:
 *     - WINDOW_INCREMENT neue Samples aus der Quell-Datei zu lesen   
 *     - insgesamt die letzten 3*WINDOW_INCREMENT Samples als Block zu betrachten und unter zweimaliger Verwendung der 
 *       Filterfunktion (siehe oben) zu filtern
 *     - die Blocks wieder zusammenzusetzen
 *     - die bei jedem Durchlauf enstehenden WINDOW_INCREMENT Samples in die Zieldatei zu schreiben
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#ifndef M_PI
# define M_PI 3.1415926535897932384626433832795
#endif


// Wichtige Parameter einer WAVE-Datei
typedef struct {
    double         samplefrequency ;
    unsigned int   channels        ;
    unsigned int   bits            ;
    unsigned long  samples         ;
    // ...
} waveinfo_t ;

// Komplexe Zahl mit 32 bit Genauigkeit (man muß ja nicht übertreiben
typedef struct {
    float  re ;
    float  im ;
} complex_float_t ;


// #include <fftw3.h>
void  fft_forward ( complex_float_t* fft_buffer, unsigned int len ) ; 
void  fft_bckward ( complex_float_t* fft_buffer, unsigned int len ) ; 

void  fft_forward ( complex_float_t* fft_buffer, unsigned int len ) {}
void  fft_bckward ( complex_float_t* fft_buffer, unsigned int len ) {}

// Fortschritt pro Arbeitsschritt, Fenstergröße ist derzeitig dreimal so groß
#define WINDOW_INCREMENT     16384
#define CHANNELS                 2      // 2.0 only


// Lesen und Analyse eines WAVE-Headers, Lesezeiger steht DANACH am Anfang der PCM-Daten
// Bei Fehler wird -1 zurückgegeben
// Streamingfähig, d.h. kein fseek() benutzt
// Analyse ist nicht vollständig und nicht idiotensicher (Division durch 0 und Überlauf bei fehlerhaften Dateien möglich)
static int
Read_Header ( waveinfo_t* const info, FILE* fp )
{
    unsigned char   Header1 [    20 ] ;
    unsigned char   Header2 [ 65536 ] ;
    unsigned char   Header3 [     8 ] ;
    unsigned long   ChunkLen ;

    fread ( Header1, 1,       20, fp ) ;

    if ( Header1 [ 0] != 'R' ) return -1 ;
    if ( Header1 [ 1] != 'I' ) return -1 ;
    if ( Header1 [ 2] != 'F' ) return -1 ;
    if ( Header1 [ 3] != 'F' ) return -1 ;
    if ( Header1 [ 8] != 'W' ) return -1 ;
    if ( Header1 [ 9] != 'A' ) return -1 ;
    if ( Header1 [10] != 'V' ) return -1 ;
    if ( Header1 [11] != 'E' ) return -1 ;
    if ( Header1 [12] != 'f' ) return -1 ;
    if ( Header1 [13] != 'm' ) return -1 ;
    if ( Header1 [14] != 't' ) return -1 ;
    if ( Header1 [15] != ' ' ) return -1 ;
    if ( Header1 [18] !=   0 ) return -1 ;
    if ( Header1 [19] !=   0 ) return -1 ;

    ChunkLen = Header1 [16] + 256 * Header1 [17];
    if ( ChunkLen < 16 )       return -1 ;
    fread ( Header2, 1, ChunkLen, fp ) ;
    fread ( Header3, 1,        8, fp ) ;

    if ( Header2 [ 0] != 0x01 ) return -1 ;
    if ( Header2 [ 1] != 0x00 ) return -1 ;

    info -> channels        = Header2 [ 2] + 256 * Header2 [ 3] ;
    info -> samplefrequency = Header2 [ 4] + 256 * Header2 [ 5] + 65536 * Header2 [ 6] + 16777216 * Header2 [ 7] ;
    info -> bits            = Header2 [14] + 256 * Header2 [15] ;
    info -> samples         = Header3 [ 4] + 256 * Header3 [ 5] + 65536 * Header3 [ 6] + 16777216 * Header3 [ 7] ;
    info -> samples        /= ( info -> bits + 7 ) / 8 * info -> channels ;

    return 0 ;
}


// Schreiben eines 44 Byte Standard-WAVE-Header, danach müssen noch die PCM-Daten geschrieben werden
// Auch hier fehlen noch ein paar Sicherheitsabfragen
static int
Write_Header ( waveinfo_t  info, FILE* fp )
{
    unsigned char   Header [44] ;
    unsigned long   word32 ;
    unsigned char*  p          = Header ;
    unsigned int    Bytes      = (info . bits + 7) / 8 ;
    double          pcmdatalen = (double) info . channels * Bytes * info . samples ;

    *p++ = 'R';
    *p++ = 'I';
    *p++ = 'F';
    *p++ = 'F';                                   // "RIFF" label

    word32 = pcmdatalen + (44 - 8) < 0xFFFFFF00  ?  (unsigned long)pcmdatalen + (44 - 8)  :  (unsigned long)0xFFFFFF00 ;
    *p++ = (unsigned char) (word32 >>  0);
    *p++ = (unsigned char) (word32 >>  8);
    *p++ = (unsigned char) (word32 >> 16);
    *p++ = (unsigned char) (word32 >> 24);        // Size of the next chunk

    *p++ = 'W';
    *p++ = 'A';
    *p++ = 'V';
    *p++ = 'E';                                   // "WAVE" label

    *p++ = 'f';
    *p++ = 'm';
    *p++ = 't';
    *p++ = ' ';                                   // "fmt " label

    *p++ = 0x10;
    *p++ = 0x00;
    *p++ = 0x00;
    *p++ = 0x00;                                  // length of the PCM data declaration = 2+2+4+4+2+2

    *p++ = 0x01;
    *p++ = 0x00;                                  // ACM type 0x0001 = uncompressed linear PCM

    word32 = info . channels ;
    *p++ = (unsigned char) (word32 >> 0);
    *p++ = (unsigned char) (word32 >> 8);              // Channels

    word32 = (unsigned long) ( info . samplefrequency + 0.5 ) ;
    *p++ = (unsigned char) (word32 >>  0);
    *p++ = (unsigned char) (word32 >>  8);
    *p++ = (unsigned char) (word32 >> 16);
    *p++ = (unsigned char) (word32 >> 24);               // Sample frequency

    word32 *= Bytes * info . channels ;
    *p++ = (unsigned char) (word32 >>  0);
    *p++ = (unsigned char) (word32 >>  8);
    *p++ = (unsigned char) (word32 >> 16);
    *p++ = (unsigned char) (word32 >> 24);               // Bytes per second in the data stream

    word32 = Bytes * info . channels ;
    *p++ = (unsigned char) (word32 >>  0);
    *p++ = (unsigned char) (word32 >>  8);               // Bytes per sample time

    word32 = info . bits ;
    *p++ = (unsigned char) (word32 >> 0);
    *p++ = (unsigned char) (word32 >> 8);         // Bits per single sample

    *p++ = 'd';
    *p++ = 'a';
    *p++ = 't';
    *p++ = 'a';                                   // "data" label

    word32 = pcmdatalen < 0xFFFFFF00  ?  (unsigned long)pcmdatalen  :  (unsigned long)0xFFFFFF00 ;
    *p++ = (unsigned char) (word32 >>  0);
    *p++ = (unsigned char) (word32 >>  8);
    *p++ = (unsigned char) (word32 >> 16);
    *p++ = (unsigned char) (word32 >> 24);               // Größe der rohen PCM-Daten

    fwrite ( Header, 1, sizeof Header, fp ) ;
    return 0 ;
}


static int
round_to_next_int ( double x )
{
    return (int) floor ( x + 0.5 ) ;
}

// Lesen der Frequenzgangdatei
// Aufbau:
//   Frequenz  Pegel
//   Frequenz  Pegel  Phase
//   # Kommentar
// Frequenzwerte müssen numerisch sortiert sein, Pegel ist in dB, Phase in Grad
static void
Read_Config ( FILE* fp, complex_float_t* frequency_response, unsigned int len, double sample_frequency )
{
    char           line [ 512 ];
    static double  fr [ 32768 ] ;
    static double  le [ 32768 ] ;
    static double  ph [ 32768 ] ;
    float          re ;
    float          im ;
    double         freq  ;
    double         level ;
    double         phase ;
    unsigned int   i ;
    int            j ;
    int            max = 0 ;

    fr [max] = 0. ;
    le [max] = 1. ;
    ph [max] = 0. ;
    max++ ;

    while ( fgets ( line, sizeof line, fp ) != NULL ) {
        switch ( line [0] ) {
        case '#' :
        case ';' :
        case '!' :
        case '\n':
            break;
        default:
            switch ( sscanf ( line, "%f%f%f", &freq, &level, &phase ) ) {
            case 2:
                fr [max]  = freq ;
                le [max]  = pow ( 10., 0.05 * level ) ;
                ph [max]  = 0. ;
                max++ ;
                break ;
            case 3:
                fr [max]  = freq ;
                le [max]  = pow ( 10., 0.05 * level ) ;
                ph [max]  = phase * ( M_PI / 180. ) ;
                // Analytische Fortsetzung
                ph [max] += 2. * M_PI * round_to_next_int ( ( ph [max-1] - ph [max] ) / ( 2. * M_PI ) ) ;
                max++ ;
                break ;
            default:
                fprintf ( stderr, "Vermurkste Zeile: %s", line ) ;
                break ;
            }
        }
    }
    fr [max] = 1.e37f ;
    le [max] = le [max-1] ;
    ph [max] = ph [max-1] ;

    j = 0 ;
    for ( i = 0; i <= len/2; i++ ) {

        freq = sample_frequency * i / len ;
        while ( fr [j + 1] <= freq )
            j++ ;

        level = ( le[j] * (fr[j+1] - freq) + le[j+1] * (freq - fr[j]) ) / ( fr[j+1] - fr[j] ) ;
        phase = ( ph[j] * (fr[j+1] - freq) + ph[j+1] * (freq - fr[j]) ) / ( fr[j+1] - fr[j] ) ;
        re    = (float) ( level * cos (phase) ) ;
        im    = (float) ( level * sin (phase) ) ;

        frequency_response [    + i] . re = +re ;
        frequency_response [    + i] . im = +im ;
        if ( i != 0 ) {
            frequency_response [len - i] . re = +re ;
            frequency_response [len - i] . im = -im ;       // Ist das richtig? Grübel?
        }
    }
}


// Frequenzgang anwenden auf fft_buffer
static void
Apply_Frequency_Response ( complex_float_t* fft_buffer, complex_float_t* frequency_response, unsigned int len )
{
    float  re ;
    float  im ;

    for ( ; len--; fft_buffer++, frequency_response++ ) {
        re             = fft_buffer->re * frequency_response->re - fft_buffer->im * frequency_response->im ;
        im             = fft_buffer->re * frequency_response->im + fft_buffer->im * frequency_response->re ;
        fft_buffer->re = re ;
        fft_buffer->im = im ;
    }
}


// Fensterfunktion berechnen und tabellieren
static void 
Init_Window ( float* Window, unsigned int len )
{
    double        x ;
    unsigned int  i ;

    for ( i = 0; i < len; i++ ) {
        x          = ( i + 0.5 ) / len - 0.5 ;
        x          = cos ( M_PI * x ) ;
        Window [i] = (float) ( x * x * sqrt (8. / 9) ) ;
    }

    // Fenstertest: Die Fenster kombiniert müssen wieder 1.000000 ergeben
    // Fensterfunktion wird vor der Analyse und Nach der Synthese ausgeführt, daher muß a² + b² + c² = 1 ergeben (und nicht a + b + c = 1 !)
    for ( i = 0; i < len/3; i++ ) {
        x = Window [i] * Window [i] + Window [i + len/3] * Window [i + len/3] + Window [i + len/3*2] * Window [i + len/3*2] ;
        fprintf ( stderr, "%5u %8.6f\n", i, x ) ;
    }
}


// Gleitkommawert auf 16 bit runden
// bei Übersteuerungen sollte sich noch der höchste Wert gemerkt werden
static short 
Quantize ( double x )
{
    int  r = (int) floor ( x + 0.5 ) ;
    if ( r != (short) r )
        r = ( r >> 31 ) ^ 0x7FFF ;
    return r ;
}


// Holly Main
int 
main ( int argc, char** argv ) 
{
    static complex_float_t  fft_buffer         [ 3 * WINDOW_INCREMENT ] ;
    static complex_float_t  frequency_response [ 3 * WINDOW_INCREMENT ] ;
    static float            fft_window         [ 3 * WINDOW_INCREMENT ] ;
    static float            input              [ CHANNELS ] [ 3 * WINDOW_INCREMENT ] ;
    static float            output             [ CHANNELS ] [ 3 * WINDOW_INCREMENT ] ;
    static short            input_quant        [ WINDOW_INCREMENT ] [ CHANNELS ] ;
    static short            output_quant       [ WINDOW_INCREMENT ] [ CHANNELS ] ;
    FILE*                   fp_input  ;
    FILE*                   fp_output ;
    FILE*                   fp_config ;
    waveinfo_t              waveinfo ;        
    unsigned long           samples_to_read ;
    unsigned long           i ;
    int                     j ;
    int                     k ;
//  fftw_complex            X_freq         ;
//  fftw_plan               X_time_to_freq ;
//  fftw_plan               X_freq_to_time ;

//  X_freq         = fftw_malloc          ( sizeof (fftw_complex) * SAMPLES_FREQ ) ;
//  X_time_to_freq = fftw_plan_dft_c2c_1d ( SAMPLES_MONO, samp_in , freq, FFTW_ESTIMATE ) ;
//  X_freq_to_time = fftw_plan_dft_c2c_1d ( SAMPLES_MONO, freq, samp_out, FFTW_ESTIMATE ) ;

//  fftw_execute ( X_time_to_freq ) ;
//  fftw_execute ( X_freq_to_time ) ;

    Init_Window  ( fft_window, 3 * WINDOW_INCREMENT ) ;

    memset ( frequency_response, 0, sizeof frequency_response ) ;
    memset ( input             , 0, sizeof input              ) ;
    memset ( output            , 0, sizeof output             ) ;

    // Dateien aufmachen, analysieren
    if ( argc != 3 ) {
        fprintf ( stderr, "Usage: %s Input.wav Output.wav Configfile\n", argv[1] ) ;
        return 1 ;
    }

    if ( ( fp_input = fopen ( argv[1], "rb" ) ) == NULL ) {
        fprintf ( stderr, "%s: Can't open '%s'\n", argv[0], argv[1] );
        return 2 ;
    }

    if ( strcmp ( argv[1], argv[2] ) == 0 ) {
        fprintf ( stderr, "%s: Input and Output file are identical: '%s' = '%s'\n", argv[0], argv[1], argv[2] );
        return 3 ;
    }

    if ( ( fp_output = fopen ( argv[2], "wb" ) ) == NULL ) {
        fprintf ( stderr, "%s: Can't create '%s'\n", argv[0], argv[2] );
        return 4 ;
    }

    if ( Read_Header ( &waveinfo, fp_input ) ) {
        fprintf ( stderr, "%s: Analysis of WAVE header failed.\n", argv[0], argv[3] );
        return 5 ;
    }

    if ( ( fp_config = fopen ( argv[3], "r" ) ) == NULL ) {
        fprintf ( stderr, "%s: Can't read config file '%s'\n", argv[0], argv[3] );
        return 6 ;
    }

    Read_Config ( fp_config, frequency_response, 3 * WINDOW_INCREMENT, waveinfo.samplefrequency ) ;
    fclose      ( fp_config ) ;

    // Letzten Vorbereitungen
    Write_Header ( waveinfo, fp_output ) ;

    // Block für Block bearbeiten
    for ( i = 0; i < waveinfo.samples; i += WINDOW_INCREMENT ) {
        fprintf ( stderr, "%4.1f sec (%2.0f%%)\r", i / waveinfo . samplefrequency, 100. * i / waveinfo.samples ) ;

        // neue Samples holen
        samples_to_read = waveinfo.samples - i ;
        if ( samples_to_read > WINDOW_INCREMENT )
            samples_to_read = WINDOW_INCREMENT ;

        memset  ( input_quant , 0           , sizeof input_quant         ) ;
        fread   ( input_quant , 2 * CHANNELS, samples_to_read, fp_input  ) ;

        // Samples bearbeiten
        for ( k = 0; k < CHANNELS; k++ ) {

            // Kanalweise umsortieren, letzten 3*WINDOW_INCREMENT Samples dabei verfügbar halten
            memmove ( input [k] + 0, input [k] + WINDOW_INCREMENT, sizeof(**input) * 2 * WINDOW_INCREMENT ) ;
            for ( j = 0; j < WINDOW_INCREMENT; j++ )
                input [k] [ 2 * WINDOW_INCREMENT + j ] = input_quant [j] [k] ;

            // Fenstern
            for ( j = 0; j < 3 * WINDOW_INCREMENT; j++ ) {
                fft_buffer [j].re = input [k] [j] * fft_window [j] ;
                fft_buffer [j].im = 0. ;
            }

            // Transformieren, Filter, Rücktransformieren
            fft_forward              ( fft_buffer, 3 * WINDOW_INCREMENT ) ; 
            Apply_Frequency_Response ( fft_buffer, frequency_response, 3 * WINDOW_INCREMENT ) ;
            fft_bckward              ( fft_buffer, 3 * WINDOW_INCREMENT ) ; 

            // Noch mal Fenstern und dabei zusammenfassen
            for ( j = 0; j < 3 * WINDOW_INCREMENT; j++ ) {
                output [k] [j] += fft_buffer [j].re * fft_window [j] ;
            }

            // Quantisieren
            for ( j = 0; j < WINDOW_INCREMENT; j++ )
                output_quant [j] [k] = Quantize ( output [k] [j] / WINDOW_INCREMENT ) ;                             // Stimmt der Pegel für fftw ???
            memmove ( output [k] + 0, output [k] + WINDOW_INCREMENT, sizeof(**output) * 2 * WINDOW_INCREMENT ) ;
        }
            
        // Und wieder schreiben
        fwrite  ( output_quant, 4, samples_to_read, fp_output ) ;  // derzeitig verzögert der Filter um 2 * WINDOW_INCREMENT
    }

    // Und alles wieder zumachen
    fprintf ( stderr, "Ready.                \n" ) ;
    fclose ( fp_input  ) ;
    fclose ( fp_output ) ;

    return 0 ;
}


Verfasst: Di 13. Jan 2004, 17:15
von ++Stefan++
Bei mir gibt es einen Fehler ohne CG-Win und zwar kann die CG-Win.dll nicht gefunden werden :cry:
Werde es aber nochmal unter Win 98 probieren weil ich CG-win bei XP schon mal installiert hatte.

Verfasst: Di 13. Jan 2004, 17:19
von JoS
schabbeskugel hat geschrieben:Und natürlich auch das Progrämmelchen, das aus einer Wav-Datei das gemittelte Frequenzspektrum 'rausspuckt.
Stelle ich auf Wunsch auch noch 'rein.
klar. nur zu!
ich habe kürzlich mit der 3d frequenzanalyse von wavelab lite herumgespielt und mich störte, dass nach unten bei 20Hz schluss ist. da ich auf anhieb kein anderes tool gefunden habe, wollte ich mir ggf. eines selber schreiben. das ist bei meinem derzeitigen kenntnisstand aber ein recht sportliches vorhaben. :roll: bis vor kurzem wusste ich nicht einmal wofür FFT steht. :oops:

ich könnte mir zwar einfach teile eurer sourcen kopieren, aber dabei lernt man ja nix :wink:

kennt jemand zufällig ein gutes buch, das die nötigen grundlagen vermittelt (signalverarbeitung, aufbau von wave-dateien) :?:

jochen

Verfasst: Di 13. Jan 2004, 17:32
von schabbeskugel
@++Stefan++: cygwin1.dll wird 'reingestellt. in wenigen Minuten. Hoffentlich reicht die dann auch. einfach in windows\system (oder so ähnlich) kopieren. Oh mein Gott, dll's hat's ja bei cygwin im Kiloweise!

@Frank Klemm: Danke für die Quellen, wenn ich Lust/Zeit habe, werde ich das ganze für die fftw3-Library anpassen, da die fft-Routinen ja noch fehlen (und ein Anführungszeichen). Aber heute nimmer.

An all diejenigen, die hoffen, dass sie ihrer NuBox310 dann Tiefstbässe entlocken können:
Wahrscheinlich bringt's nicht viel, da man den Bass-Pegel sonst ganz gewaltig erhöhen müßte (>20db= x100), da kommen schnell 100 Watt zusammen. (Ggf. wird der auftretende Dopplereffekt und die verstärkten Verzerrungen durch die höheren Pegel nicht gerade zu Freudensprüngen führen).

Verfasst: Di 13. Jan 2004, 17:35
von schabbeskugel
@Frank Klemm: Der Name "Schabbesfilter" ehrt mich sehr. Warum nicht? Ist ja Gott sei dank nicht mein Name :-)

Verfasst: Di 13. Jan 2004, 18:07
von Frank Klemm
schabbeskugel hat geschrieben:@++Stefan++: cygwin1.dll wird 'reingestellt. in wenigen Minuten. Hoffentlich reicht die dann auch. einfach in windows\system (oder so ähnlich) kopieren. Oh mein Gott, dll's hat's ja bei cygwin im Kiloweise!

@Frank Klemm: Danke für die Quellen, wenn ich Lust/Zeit habe, werde ich das ganze für die fftw3-Library anpassen, da die fft-Routinen ja noch fehlen (und ein Anführungszeichen). Aber heute nimmer.
Das ganz ist vollständig ungetestet. Ich kann es nicht testen, es soll aber den prinzipiellen
Weg zeigen. Neben dem Pegel sollte auch die Phase korrigierbar sein.

Dazu müßte man aber auch den Phasenfrequenzgang kennen.

Eine dynamisch angepaßte Entzerrung kann auch aufgenommen werden.
Dazu sind dynamische Frequenzgänge, z.B. bei 84 dB, 90 dB, 96 dB
erforderlich.
Hauptproblem ist aber die Stellung des Lautstärkerreglers (3 Stück gibt es davon!),
den man kennen muß.
Vielleicht schleichen wir uns an die Lösung langsam ran ;-)

Verfasst: Di 13. Jan 2004, 19:48
von ++Stefan++
Schon wieder ein Problem:
Die exe Startet, schleißt sich aber gleich wieder.
Es wird als erstes ein Text gezeigt und danach kommen 2 Meldungen.
Die Meldungen kann ich aber fast nicht sehen.
Mit der Pause-Taste lässt sich das ganze auch nicht an der richtigen stelle anhalten, sodass diese nicht enziffert werden könnten

Wird im Programm angegeben, wo sich die Dateien (WAV, und abl.txt) befinden?
Oder muss man das programm auf eine bestimmte Art ausführen ?

Ich habe davon echt keine Ahnung, also habt Mittleid mit einem nicht Programmierer.

Verfasst: Di 13. Jan 2004, 20:10
von Frank Klemm
++Stefan++ hat geschrieben:Schon wieder ein Problem:
Die exe Startet, schleißt sich aber gleich wieder.
Es wird als erstes ein Text gezeigt und danach kommen 2 Meldungen.
Die Meldungen kann ich aber fast nicht sehen.
Mit der Pause-Taste lässt sich das ganze auch nicht an der richtigen stelle anhalten, sodass diese nicht enziffert werden könnten

Wird im Programm angegeben, wo sich die Dateien (WAV, und abl.txt) befinden?
Oder muss man das programm auf eine bestimmte Art ausführen ?

Ich habe davon echt keine Ahnung, also habt Mittleid mit einem nicht Programmierer.
Not all is a clickable.
Das hat nichts mit Programmierer oder Nichtprogrammierer zu tun.

Start | Run
cmd (NT, 2K, XP) oder command (95, 98, ME) eingeben
ENTER
Programmname gefolgt von Argumenten eingeben
ENTER

Verfasst: Di 13. Jan 2004, 20:33
von ++Stefan++
Ich habe das ganze leider nur mit der ausführenzeile versucht danke.
Ich hoffe ich war nicht der einzige, der diesen Fehler begangen hat, ist mir fast schon peinlich.

ABER nun kommen bei mir entweder 0kb dateien heraus oder bei genau gleicher eingabe eine 147kb datei die angeblich in ordnung sein soll (-7.02db).

Wieder ein Anwenderfehler?