-         

Seite 1 von 24 12311 ... LetzteLetzte
Ergebnis 1 bis 10 von 240

Thema: wav Dateien: Programieren von Wiedergabe und Aufnahme

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.451

    wav Dateien: Programmieren von Wiedergabe und Aufnahme

    Anzeige

    hallo,
    ich mach mal hier eine eigenes Topic, leider ist es ja offenbar doch viel komplizierter als ursprünglich gedacht...

    Ich Suche (auch) für mich eine einfache wav C/C++ API lib.
    Eine gute Basis scheint zur Zeit die sehr komplexe ALSA lib als Basis zu bieten, aber als Vereinfachung dazu könnte tinyalsa sein:
    https://github.com/tinyalsa/tinyalsa

    Installation:

    Code:
    git clone https://github.com/tinyalsa/tinyalsa.git
    cd tinyalsa
    make
    wenn ich damit allerdings das (allerdings immer noch viel zu umfangreiche) Codebeispiel
    https://github.com/tinyalsa/tinyalsa...ter/tinyplay.c
    kompiliere, wird trotzdem eine wichtige lib zum Verlinken nicht gefunden.
    Ich arbeite ausschließlich mit Geany.

    Code:
    /* tinyplay.c
    **
    ** Copyright 2011, The Android Open Source Project
    **
    ** Redistribution and use in source and binary forms, with or without
    ** modification, are permitted provided that the following conditions are met:
    **     * Redistributions of source code must retain the above copyright
    **       notice, this list of conditions and the following disclaimer.
    **     * Redistributions in binary form must reproduce the above copyright
    **       notice, this list of conditions and the following disclaimer in the
    **       documentation and/or other materials provided with the distribution.
    **     * Neither the name of The Android Open Source Project nor the names of
    **       its contributors may be used to endorse or promote products derived
    **       from this software without specific prior written permission.
    **
    ** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
    ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
    ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    ** DAMAGE.
    */
    
    #include <tinyalsa/asoundlib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    #include <signal.h>
    
    #define ID_RIFF 0x46464952
    #define ID_WAVE 0x45564157
    #define ID_FMT  0x20746d66
    #define ID_DATA 0x61746164
    
    struct riff_wave_header {
        uint32_t riff_id;
        uint32_t riff_sz;
        uint32_t wave_id;
    };
    
    struct chunk_header {
        uint32_t id;
        uint32_t sz;
    };
    
    struct chunk_fmt {
        uint16_t audio_format;
        uint16_t num_channels;
        uint32_t sample_rate;
        uint32_t byte_rate;
        uint16_t block_align;
        uint16_t bits_per_sample;
    };
    
    static int close = 0;
    
    void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                     unsigned int rate, unsigned int bits, unsigned int period_size,
                     unsigned int period_count);
    
    void stream_close(int sig)
    {
        /* allow the stream to be closed gracefully */
        signal(sig, SIG_IGN);
        close = 1;
    }
    
    int main(int argc, char **argv)
    {
        FILE *file;
        struct riff_wave_header riff_wave_header;
        struct chunk_header chunk_header;
        struct chunk_fmt chunk_fmt;
        unsigned int device = 0;
        unsigned int card = 0;
        unsigned int period_size = 1024;
        unsigned int period_count = 4;
        unsigned int channels = 2;
        unsigned int rate = 48000;
        unsigned int bits = 16;
        unsigned int is_raw = 0; /* Default wav file */
        char *filename;
        int more_chunks = 1;
    
        if (argc < 2) {
            fprintf(stderr, "Usage1: %s file.wav [-D card] [-d device] [-p period_size]"
                    " [-n n_periods] \n", argv[0]);
            fprintf(stderr, "Usage2: %s file.raw [-D card] [-d device] [-p period_size] "
                    "[-n n_periods] [-c channels] [-r rate] [-b bits] -i raw \n", argv[0]);
            return 1;
        }
    
        filename = argv[1];
        file = fopen(filename, "rb");
        if (!file) {
            fprintf(stderr, "Unable to open file '%s'\n", filename);
            return 1;
        }
    
        /* parse command line arguments */
        argv += 2;
        while (*argv) {
            if (strcmp(*argv, "-d") == 0) {
                argv++;
                if (*argv)
                    device = atoi(*argv);
            }
            if (strcmp(*argv, "-p") == 0) {
                argv++;
                if (*argv)
                    period_size = atoi(*argv);
            }
            if (strcmp(*argv, "-n") == 0) {
                argv++;
                if (*argv)
                    period_count = atoi(*argv);
            }
            if (strcmp(*argv, "-D") == 0) {
                argv++;
                if (*argv)
                    card = atoi(*argv);
            }
            if (strcmp(*argv, "-c") == 0) {
                argv++;
                if (*argv)
                    channels = atoi(*argv);
            }
            if (strcmp(*argv, "-r") == 0) {
                argv++;
                if (*argv)
                    rate = atoi(*argv);
            }
            if (strcmp(*argv, "-b") == 0) {
                argv++;
                if (*argv)
                    bits = atoi(*argv);
            }
            if (strcmp(*argv, "-i") == 0) {
                argv++;
                if (*argv) {
                    if (strcasecmp(*argv, "raw") == 0) {
                        is_raw = 1;
                    }
                }
            }
            if (*argv)
                argv++;
        }
    
        if ( !is_raw ) {
            fread(&riff_wave_header, sizeof(riff_wave_header), 1, file);
            if ((riff_wave_header.riff_id != ID_RIFF) ||
                (riff_wave_header.wave_id != ID_WAVE)) {
                fprintf(stderr, "Error: '%s' is not a riff/wave file\n", filename);
                fclose(file);
                return 1;
            }
            do {
                fread(&chunk_header, sizeof(chunk_header), 1, file);
                switch (chunk_header.id) {
                case ID_FMT:
                    fread(&chunk_fmt, sizeof(chunk_fmt), 1, file);
                    /* If the format header is larger, skip the rest */
                    if (chunk_header.sz > sizeof(chunk_fmt))
                        fseek(file, chunk_header.sz - sizeof(chunk_fmt), SEEK_CUR);
                    break;
                case ID_DATA:
                    /* Stop looking for chunks */
                    more_chunks = 0;
                    break;
                default:
                    /* Unknown chunk, skip bytes */
                    fseek(file, chunk_header.sz, SEEK_CUR);
                }
            } while (more_chunks);
            channels = chunk_fmt.num_channels;
            rate = chunk_fmt.sample_rate;
            bits = chunk_fmt.bits_per_sample;
        }
    
        play_sample(file, card, device, channels, rate, bits, period_size, period_count);
    
        fclose(file);
    
        return 0;
    }
    
    int check_param(struct pcm_params *params, unsigned int param, unsigned int value,
                     char *param_name, char *param_unit)
    {
        unsigned int min;
        unsigned int max;
        int is_within_bounds = 1;
    
        min = pcm_params_get_min(params, param);
        if (value < min) {
            fprintf(stderr, "%s is %u%s, device only supports >= %u%s\n", param_name, value,
                    param_unit, min, param_unit);
            is_within_bounds = 0;
        }
    
        max = pcm_params_get_max(params, param);
        if (value > max) {
            fprintf(stderr, "%s is %u%s, device only supports <= %u%s\n", param_name, value,
                    param_unit, max, param_unit);
            is_within_bounds = 0;
        }
    
        return is_within_bounds;
    }
    
    int sample_is_playable(unsigned int card, unsigned int device, unsigned int channels,
                            unsigned int rate, unsigned int bits, unsigned int period_size,
                            unsigned int period_count)
    {
        struct pcm_params *params;
        int can_play;
    
        params = pcm_params_get(card, device, PCM_OUT);
        if (params == NULL) {
            fprintf(stderr, "Unable to open PCM device %u.\n", device);
            return 0;
        }
    
        can_play = check_param(params, PCM_PARAM_RATE, rate, "Sample rate", "Hz");
        can_play &= check_param(params, PCM_PARAM_CHANNELS, channels, "Sample", " channels");
        can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, bits, "Bitrate", " bits");
        can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, period_size, "Period size", "Hz");
        can_play &= check_param(params, PCM_PARAM_PERIODS, period_count, "Period count", "Hz");
    
        pcm_params_free(params);
    
        return can_play;
    }
    
    void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                     unsigned int rate, unsigned int bits, unsigned int period_size,
                     unsigned int period_count)
    {
        struct pcm_config config;
        struct pcm *pcm;
        char *buffer;
        int size;
        int num_read;
    
        memset(&config, 0, sizeof(config));
        config.channels = channels;
        config.rate = rate;
        config.period_size = period_size;
        config.period_count = period_count;
        if (bits == 32)
            config.format = PCM_FORMAT_S32_LE;
        else if (bits == 16)
            config.format = PCM_FORMAT_S16_LE;
        config.start_threshold = 0;
        config.stop_threshold = 0;
        config.silence_threshold = 0;
    
        if (!sample_is_playable(card, device, channels, rate, bits, period_size, period_count)) {
            return;
        }
    
        pcm = pcm_open(card, device, PCM_OUT, &config);
        if (!pcm || !pcm_is_ready(pcm)) {
            fprintf(stderr, "Unable to open PCM device %u (%s)\n",
                    device, pcm_get_error(pcm));
            return;
        }
    
        size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
        buffer = malloc(size);
        if (!buffer) {
            fprintf(stderr, "Unable to allocate %d bytes\n", size);
            free(buffer);
            pcm_close(pcm);
            return;
        }
    
        printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);
    
        /* catch ctrl-c to shutdown cleanly */
        signal(SIGINT, stream_close);
    
        do {
            num_read = fread(buffer, 1, size, file);
            if (num_read > 0) {
                if (pcm_write(pcm, buffer, num_read)) {
                    fprintf(stderr, "Error playing sample\n");
                    break;
                }
            }
        } while (!close && num_read > 0);
    
        free(buffer);
        pcm_close(pcm);
    }
    compilation error:

    g++ -Wall -pthread -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -c "tinyplay0000.c" -lshapes -lwiringPi -lrt -lpigpio -std=c++11 (im Verzeichnis: /home/pi/Desktop/pi/programs/soundprogs)
    tinyplay0000.c:29:32: fatal error: tinyalsa/asoundlib.h: Datei oder Verzeichnis nicht gefunden
    #include <tinyalsa/asoundlib.h>

    compilation terminated.
    Kompilierung fehlgeschlagen.
    Fehlt noch was für die korrekte Installation der Lib?
    Was muss ich ggf. für Geany dazulinken?
    Geändert von HaWe (21.05.2016 um 12:39 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Hallo,

    das ist ein Compiler Fehler, weil er nicht den Pfad zum Include Directory kennt, wo die tinyalsa lib liegt. Deine installation von oben befördert die Lib nicht in irgendwelche Standardpfade.
    Da muß also noch ein
    Code:
     -I/wo/immer/liegt/tinyalsa/include
    ins makefile rein dann auch ein
    Code:
    -L/wo/immer/liegt/tinyalsa/lib
    sonst meckert später der Linker.

    Gruß

    Chris
    Geändert von botty (21.05.2016 um 13:37 Uhr)

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.451
    aha....?
    ich dachte, weil doch oben im include schon der Pfad steht, müsste er's wissen..:
    #include <tinyalsa/asoundlib.h>

    aber stimmt ja auch, es gibt ja gar kein Verzeichnis
    /tinyalsa/

    wo ist dann die lib hin installiert worden?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Guck mal kurz ins Makefile vom tinyalsa. Es gibt kein 'install' target, sprich die lib wird nicht nach /opt-oder-sonstwohin gelegt, sodass g++ das Ding über die Standardpfade finden kann. Statt dessen liegt alles in dem Verzeichnis wohin Du den Source gepackt hast und das *.h file im include Verzeichnis darunter.
    Die Pfade mußt Du Deiner IDE/makefile mitgeben und dann auch noch ein
    Code:
    -ltinyalsa
    für die Library selbst beim Linken, sorry hatte ich oben vergessen.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.451
    aha, hier ist was:

    /home/pi/tinyalsa/

    das ist jetzt ein ziemlich blöder Speicherort, warum nicht global ?
    Ich verschiebs mal nach /lib/tinyalsa....

    Schei**e, keine Berechtigung.
    Was ein Dreck.
    Ich HASSE Linux.

    wie kann ich das Verzeichnis umändern?

    - - - Aktualisiert - - -

    hm,
    sudo cp -rf ... ...
    hat geklappt.

    ok.

    jetzt also als Zusatz-Parameter für compile und build:

    Code:
    -I/lib/tinyalsa/include  -L/lib/tinyalsa/lib  -ltinyalsa
    richtig?

    auch
    -L/lib/tinyalsa/lib
    ist richtig??? wieso nochmal lib am Schluss?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    nein kein lib am ende.

    du müßtest jetzt die dateien

    /lib/tinyalsa/libtinyalsa.so
    /lib/tinyalsa/libtinyalsa.a

    haben. Damit muß

    Code:
    -I/lib/tinyalsa/include  -L/lib/tinyalsa  -ltinyalsa
    lauten.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.451
    g++ -Wall -pthread -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -c "tinyplay0000.c" -lshapes -lwiringPi -lrt -lpigpio -I/lib/tinyalsa/include -L/lib/tinyalsa -ltinyalsa -std=c++11 (im Verzeichnis: /home/pi/Desktop/pi/programs/soundprogs)
    tinyplay0000.c: In function ‘int check_param(pcm_params*, unsigned int, unsigned int, char*, char*)’:
    tinyplay0000.c:201:43: error: invalid conversion from ‘unsigned int’ to ‘pcm_param’ [-fpermissive]
    min = pcm_params_get_min(params, param);
    ^
    In file included from tinyplay0000.c:29:0:
    /lib/tinyalsa/include/tinyalsa/asoundlib.h:151:14: note: initializing argument 2 of ‘unsigned int pcm_params_get_min(pcm_params*, pcm_param)’
    unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
    ^
    tinyplay0000.c:208:43: error: invalid conversion from ‘unsigned int’ to ‘pcm_param’ [-fpermissive]
    max = pcm_params_get_max(params, param);
    ^
    In file included from tinyplay0000.c:29:0:
    /lib/tinyalsa/include/tinyalsa/asoundlib.h:153:14: note: initializing argument 2 of ‘unsigned int pcm_params_get_max(pcm_params*, pcm_param)’
    unsigned int pcm_params_get_max(struct pcm_params *pcm_params,
    ^
    tinyplay0000.c: In function ‘int sample_is_playable(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)’:
    tinyplay0000.c:231:77: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    can_play = check_param(params, PCM_PARAM_RATE, rate, "Sample rate", "Hz");
    ^
    tinyplay0000.c:231:77: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    tinyplay0000.c:232:88: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    can_play &= check_param(params, PCM_PARAM_CHANNELS, channels, "Sample", " channels");
    ^
    tinyplay0000.c:232:88: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    tinyplay0000.c:233:84: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, bits, "Bitrate", " bits");
    ^
    tinyplay0000.c:233:84: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    tinyplay0000.c:234:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, period_size, "Period size", "Hz");
    ^
    tinyplay0000.c:234:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    tinyplay0000.c:235:90: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    can_play &= check_param(params, PCM_PARAM_PERIODS, period_count, "Period count", "Hz");
    ^
    tinyplay0000.c:235:90: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    tinyplay0000.c: In function ‘void play_sample(FILE*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)’:
    tinyplay0000.c:277:25: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
    buffer = malloc(size);
    ^
    Kompilierung fehlgeschlagen.



    was ein Mist

    - - - Aktualisiert - - -

    du müßtest jetzt die dateien

    /lib/tinyalsa/libtinyalsa.so
    /lib/tinyalsa/libtinyalsa.a
    ja, habe ich.
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    das ist ein c und kein c++ beispiel!
    kompilier das mal mit GCC und nicht g++.

    die fehler die hier auftreten beruhen darauf das enums in c++ klassen und nicht unsigned ints sind.
    auch die typprüfung von buffer ganz unten beruht auf dem strikterem c++ typsystem.
    Geändert von botty (21.05.2016 um 17:36 Uhr)

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.451
    das geht dann nicht, weil wav files ein Teil eines C++ Projekts werden müssen.
    Kann man die lib umschreiben auf C++ Kompatibilität?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Es ist das Beispiel, dass nicht sauber ist, nicht die Bibliothek.

    Leider mußt Du noch was anderes machen, da habe ich nicht aufgepaßt.
    Entweder Du verschiebst die /lib/tinyalsa/libtinyalsa.* nach /usr/local/lib oder du machst einen symbolischen link in /usr/local/lib auf diese Dateien, sonst findet der Linker zur Laufzeit die Libs nicht.

    Ansonsten sollte dieses modifizierte Beispiel sich kompilieren und starten lassen, zumindest auf meinem Lappi hat das geklappt.


    Gruß
    Chris

    Code:
    /* tinyplay.c
    **
    ** Copyright 2011, The Android Open Source Project
    **
    ** Redistribution and use in source and binary forms, with or without
    ** modification, are permitted provided that the following conditions are met:
    **     * Redistributions of source code must retain the above copyright
    **       notice, this list of conditions and the following disclaimer.
    **     * Redistributions in binary form must reproduce the above copyright
    **       notice, this list of conditions and the following disclaimer in the
    **       documentation and/or other materials provided with the distribution.
    **     * Neither the name of The Android Open Source Project nor the names of
    **       its contributors may be used to endorse or promote products derived
    **       from this software withplay_cpp.cout specific prior written permission.
    **
    ** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
    ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
    ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    ** DAMAGE.
    */
    
    #include <tinyalsa/asoundlib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    #include <signal.h>
    
    #define ID_RIFF 0x46464952
    #define ID_WAVE 0x45564157
    #define ID_FMT  0x20746d66
    #define ID_DATA 0x61746164
    
    struct riff_wave_header {
        uint32_t riff_id;
        uint32_t riff_sz;
        uint32_t wave_id;
    };
    
    struct chunk_header {
        uint32_t id;
        uint32_t sz;
    };
    
    struct chunk_fmt {
        uint16_t audio_format;
        uint16_t num_channels;
        uint32_t sample_rate;
        uint32_t byte_rate;
        uint16_t block_align;
        uint16_t bits_per_sample;
    };
    
    static int close = 0;
    
    void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                     unsigned int rate, unsigned int bits, unsigned int period_size,
                     unsigned int period_count);
    
    void stream_close(int sig)
    {
        /* allow the stream to be closed gracefully */
        signal(sig, SIG_IGN);
        close = 1;
    }
    
    int main(int argc, char **argv)
    {
        FILE *file;
        struct riff_wave_header riff_wave_header;
        struct chunk_header chunk_header;
        struct chunk_fmt chunk_fmt;
        unsigned int device = 0;
        unsigned int card = 0;
        unsigned int period_size = 1024;
        unsigned int period_count = 4;
        unsigned int channels = 2;
        unsigned int rate = 48000;
        unsigned int bits = 16;
        unsigned int is_raw = 0; /* Default wav file */
        char *filename;
        int more_chunks = 1;
    
        if (argc < 2) {
            fprintf(stderr, "Usage1: %s file.wav [-D card] [-d device] [-p period_size]"
                    " [-n n_periods] \n", argv[0]);
            fprintf(stderr, "Usage2: %s file.raw [-D card] [-d device] [-p period_size] "
                    "[-n n_periods] [-c channels] [-r rate] [-b bits] -i raw \n", argv[0]);
            return 1;
        }
    
        filename = argv[1];
        file = fopen(filename, "rb");
        if (!file) {
            fprintf(stderr, "Unable to open file '%s'\n", filename);
            return 1;
        }
    
        /* parse command line arguments */
        argv += 2;
        while (*argv) {
            if (strcmp(*argv, "-d") == 0) {
                argv++;
                if (*argv)
                    device = atoi(*argv);
            }
            if (strcmp(*argv, "-p") == 0) {
                argv++;
                if (*argv)
                    period_size = atoi(*argv);
            }
            if (strcmp(*argv, "-n") == 0) {
                argv++;
                if (*argv)
                    period_count = atoi(*argv);
            }
            if (strcmp(*argv, "-D") == 0) {
                argv++;
                if (*argv)
                    card = atoi(*argv);
            }
            if (strcmp(*argv, "-c") == 0) {
                argv++;
                if (*argv)
                    channels = atoi(*argv);
            }
            if (strcmp(*argv, "-r") == 0) {
                argv++;
                if (*argv)
                    rate = atoi(*argv);
            }
            if (strcmp(*argv, "-b") == 0) {
                argv++;
                if (*argv)
                    bits = atoi(*argv);
            }
            if (strcmp(*argv, "-i") == 0) {
                argv++;
                if (*argv) {
                    if (strcasecmp(*argv, "raw") == 0) {
                        is_raw = 1;
                    }
                }
            }
            if (*argv)
                argv++;
        }
    
        if ( !is_raw ) {
            fread(&riff_wave_header, sizeof(riff_wave_header), 1, file);
            if ((riff_wave_header.riff_id != ID_RIFF) ||
                (riff_wave_header.wave_id != ID_WAVE)) {
                fprintf(stderr, "Error: '%s' is not a riff/wave file\n", filename);
                fclose(file);
                return 1;
            }
            do {
                fread(&chunk_header, sizeof(chunk_header), 1, file);
                switch (chunk_header.id) {
                case ID_FMT:
                    fread(&chunk_fmt, sizeof(chunk_fmt), 1, file);
                    /* If the format header is larger, skip the rest */
                    if (chunk_header.sz > sizeof(chunk_fmt))
                        fseek(file, chunk_header.sz - sizeof(chunk_fmt), SEEK_CUR);
                    break;
                case ID_DATA:
                    /* Stop looking for chunks */
                    more_chunks = 0;
                    break;
                default:
                    /* Unknown chunk, skip bytes */
                    fseek(file, chunk_header.sz, SEEK_CUR);
                }
            } while (more_chunks);
            channels = chunk_fmt.num_channels;
            rate = chunk_fmt.sample_rate;
            bits = chunk_fmt.bits_per_sample;
        }
    
        play_sample(file, card, device, channels, rate, bits, period_size, period_count);
    
        fclose(file);
    
        return 0;
    }
    
    int check_param(struct pcm_params *params, enum pcm_param param,
    		unsigned int value, const char *param_name, 
    		const char *param_unit)
    {
        unsigned int min;
        unsigned int max;
        int is_within_bounds = 1;
    
        min = pcm_params_get_min(params, param);
        if (value < min) {
            fprintf(stderr, "%s is %u%s, device only supports >= %u%s\n", param_name, value,
                    param_unit, min, param_unit);
            is_within_bounds = 0;
        }
    
        max = pcm_params_get_max(params, param);
        if (value > max) {
            fprintf(stderr, "%s is %u%s, device only supports <= %u%s\n", param_name, value,
                    param_unit, max, param_unit);
            is_within_bounds = 0;
        }
    
        return is_within_bounds;
    }
    
    int sample_is_playable(unsigned int card, unsigned int device, unsigned int channels,
                            unsigned int rate, unsigned int bits, unsigned int period_size,
                            unsigned int period_count)
    {
        struct pcm_params *params;
        int can_play;
    
        params = pcm_params_get(card, device, PCM_OUT);
        if (params == NULL) {
            fprintf(stderr, "Unable to open PCM device %u.\n", device);
            return 0;
        }
    
        can_play = check_param(params, PCM_PARAM_RATE, rate, "Sample rate", "Hz");
        can_play &= check_param(params, PCM_PARAM_CHANNELS, channels, "Sample", " channels");
        can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, bits, "Bitrate", " bits");
        can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, period_size, "Period size", "Hz");
        can_play &= check_param(params, PCM_PARAM_PERIODS, period_count, "Period count", "Hz");
    
        pcm_params_free(params);
    
        return can_play;
    }
    
    void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                     unsigned int rate, unsigned int bits, unsigned int period_size,
                     unsigned int period_count)
    {
        struct pcm_config config;
        struct pcm *pcm;
        char *buffer;
        int size;
        int num_read;
    
        memset(&config, 0, sizeof(config));
        config.channels = channels;
        config.rate = rate;
        config.period_size = period_size;
        config.period_count = period_count;
        if (bits == 32)
            config.format = PCM_FORMAT_S32_LE;
        else if (bits == 16)
            config.format = PCM_FORMAT_S16_LE;
        config.start_threshold = 0;
        config.stop_threshold = 0;
        config.silence_threshold = 0;
    
        if (!sample_is_playable(card, device, channels, rate, bits, period_size, period_count)) {
            return;
        }
    
        pcm = pcm_open(card, device, PCM_OUT, &config);
        if (!pcm || !pcm_is_ready(pcm)) {
            fprintf(stderr, "Unable to open PCM device %u (%s)\n",
                    device, pcm_get_error(pcm));
            return;
        }
    
        size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
        buffer = (char *)malloc(size);
        if (!buffer) {
            fprintf(stderr, "Unable to allocate %d bytes\n", size);
            free(buffer);
            pcm_close(pcm);
            return;
        }
    
        printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);
    
        /* catch ctrl-c to shutdown cleanly */
        signal(SIGINT, stream_close);
    
        do {
            num_read = fread(buffer, 1, size, file);
            if (num_read > 0) {
                if (pcm_write(pcm, buffer, num_read)) {
                    fprintf(stderr, "Error playing sample\n");
                    break;
                }
            }
        } while (!close && num_read > 0);
    
        free(buffer);
        pcm_close(pcm);
    }

Seite 1 von 24 12311 ... LetzteLetzte

Ähnliche Themen

  1. Video Aufnahme (+12std.)
    Von highdef im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 8
    Letzter Beitrag: 03.06.2011, 11:08
  2. led ein/aus programieren
    Von anthony im Forum PIC Controller
    Antworten: 6
    Letzter Beitrag: 15.07.2008, 18:44
  3. hex-dateien in bin-dateien umwandeln
    Von roboterheld im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 02.10.2007, 21:25
  4. Richtiges Drehen einer Flasche/Dose zur Aufnahme
    Von ähM_Key im Forum Mechanik
    Antworten: 2
    Letzter Beitrag: 06.10.2006, 16:43
  5. Automatische Audio-Aufnahme
    Von the_Ghost666 im Forum Software, Algorithmen und KI
    Antworten: 6
    Letzter Beitrag: 11.09.2005, 21:27

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •