Soundkarte unte Linux mit C



  • Hallo alle zusammen. Ich versuch eine wave Datei über die soudkarte abzuspielen, aber es funktioniert leider nicht. Wäre euch dankbar wenn ihr mir einen tipp geben könnt.

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <linux/soundcard.h>

    #define SOUND_DEVICE "/dev/dsp"
    #define NUM_SAMPLES 100000

    unsigned char buffer[NUM_SAMPLES];

    int main()
    {
    int fd,i,format=AFMT_U8;
    long length;
    char input[16];

    /*ein File öffnen*/
    FILE *sound_file;

    /öffnen des devices/
    if ((fd=open(SOUND_DEVICE, O_RDWR))==-1)
    {
    perror("Can't open device");
    return(1);
    }

    /*Format des devices*/
    if(ioctl(fd,SNDCTL_DSP_SETFMT, &format)==-1)
    perror("Can't set format");

    /*mono*/
    i=0;
    if (ioctl(fd, SNDCTL_DSP_STEREO, &i)==-1)
    perror("Can't set mono");

    /*Abtastfrequenz*/
    i=22050;
    if(ioctl(fd,SNDCTL_DSP_SPEED,&i)==-1)
    perror("Can't set sampling rate");

    sound_file=fopen("/home/6.wav", "r");
    if ((sound_file=fopen("/home/6.wav", "r"))==NULL)
    {
    perror("Can't open soundfile");
    return(1);
    }
    fgets (input,16,sound_file);

    while (!feof(sound_file))
    {

    if (write(fd,sound_file,length)==-1)
    {
    perror("Can't play audio data");
    }

    }

    fclose(sound_file);
    close(fd);
    return(0);
    }

    Nun wenn ich das ganze kompiliere und debugge(gcc -g sound.c) ist alle ok
    bis irgendwann die Meldung kommt Can't play audio data. WARUM?



  • sfds Bitte benutz Syntax-Highlight!

    Du liest die .wav-Datei als Textdatei ein (mit fgets). Das ist natürlich problematisch bei binär-Dateien. Benutz am besten man: mmap(2) oder man: read(2)/man: fread(3)

    LOL und das was du da machst if (write(fd,sound_file,length)==-1) kann ja auch nicht gehen. Du schreibst einfach nur ewig den Dateihandler in das Sound-Device. Siehe auch man: write(2)



  • rüdiger schrieb:

    <a target='_blank' href='viewtopic.php?t=39411'>So funktioniert das Syntaxcoloring:</a> Bitte benutz Syntax-Highlight!

    Du liest die .wav-Datei als Textdatei ein (mit fgets). Das ist natürlich problematisch bei binär-Dateien. Benutz am besten man: mmap(2) oder man: read(2)/man: fread(3)

    LOL und das was du da machst if (write(fd,sound_file,length)==-1) kann ja auch nicht gehen. Du schreibst einfach nur ewig den Dateihandler in das Sound-Device. Siehe auch man: write(2)

    hallo rüdiger und alle anderen, leider brauche ich etwas ausführliche einleitung. wie benutze ich read/fread in meinem Fall. bin für jede Hilfe DANKBAR!



  • Dieser Thread wurde von Moderator/in Tim aus dem Forum ANSI C in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Schaubert schrieb:

    [...]

    hallo rüdiger und alle anderen, leider brauche ich etwas ausführliche einleitung. wie benutze ich read/fread in meinem Fall. bin für jede Hilfe DANKBAR!

    Schau mal hier: hier!

    Dann solltest du dir vielleicht auch noch ein gutes Buch zulegen...



  • ProgChild schrieb:

    [..] Dann solltest du dir vielleicht auch noch ein gutes Buch zulegen...

    Vielleicht dieses hier: "C und Linux" 😃

    Darin sind das Ansteuern der Sound-Karte über OSS (Open Sound System), der Umgang mit Dateien / Streams, sowie das WAV-Dateiformat explizit beschrieben!

    Martin



  • Martin G schrieb:

    ProgChild schrieb:

    [..] Dann solltest du dir vielleicht auch noch ein gutes Buch zulegen...

    Vielleicht dieses hier: "C und Linux" 😃

    Darin sind das Ansteuern der Sound-Karte über OSS (Open Sound System), der Umgang mit Dateien / Streams, sowie das WAV-Dateiformat explizit beschrieben!

    Martin

    hallo Martin habe übrigens jetzt dein buch, sehr gut geschrieben aber mir fehlt erlich gesagt noch die nötige erfarung um bei devices und anwendungen durchzustarten.
    Aber zurück zu dem thema das auslesen der .wav files beginnt, ich vermute, mit header auslesen und so weiter.... Hat vielleicht jemand einen passsenden link zu dem thema oder ein tutorial?



  • Schaubert schrieb:

    hallo Martin habe übrigens jetzt dein buch, sehr gut geschrieben aber mir fehlt erlich gesagt noch die nötige erfarung um bei devices und anwendungen durchzustarten.
    Aber zurück zu dem thema das auslesen der .wav files beginnt, ich vermute, mit header auslesen und so weiter.... Hat vielleicht jemand einen passsenden link zu dem thema oder ein tutorial?

    Wenn ich mich richtig erinner, war im Anhang zu der Ausgabe, die ich besitze, eine Beschreibung des .WAV Dateiformats.



  • Schaubert schrieb:

    [...] Aber zurück zu dem thema das auslesen der .wav files beginnt, ich vermute, mit header auslesen und so weiter.... Hat vielleicht jemand einen passsenden link zu dem thema oder ein tutorial?

    Für die Verarbeitung von WAV-Dateien (Fourier-Transformation etc.) habe ich mal ein kleines Programm geschrieben, das WAV-Dateien einliest und als Text (Zeit, Amplitude) wieder ausgibt. Den Anfang des Quelltextes - nämlich den Teil, der den Header einliest, habe ich hier mal gepostet:

    /*
            wav2dat.c
            WAV-Audio-Dateien in XY-ASCII wandeln
    */
    
    # include <stdio.h>
    # include <string.h>
    
    unsigned long char2long(unsigned char *buffer)
     {
      int i;
      unsigned long value;
    
      value = 0;
      for (i=0; i<4; i++)
        value |= buffer[i] << (i*8);
      return(value);
     }
    
    int read_bytes(FILE *stream, char *buffer, unsigned long n)
     {
      int c;
      unsigned long i;
    
      for (i=0; i<n; i++)
        if ((c = fgetc(stream)) == EOF)
          return(-1);
        else
          buffer[i] = c;
      return(0);
     }
    
    /*----------------------------------------------------------------------*/
    
    int main(int argc, char *argv[])
     {
      char buffer[12];
      unsigned char c1, c2;
      unsigned long length, samples, freq, n;
      int channels, bits_per_sample, i;
      short value[4];
      FILE *in_stream, *out_stream;
    
      if ((argc > 3) || ((argc > 1) && (strcmp(argv[1], "-h") == 0)))
       {
        printf("Usage: wav2dat [wav-file [dat-file]]\n");
        return(0);
       }
    
      if (argc == 1)
        in_stream = stdin;
      else
        if ((in_stream=fopen(argv[1], "r")) == NULL)
         {
          fprintf(stderr, "wav2dat: Can't open input file '%s'.\n", argv[1]);
          return(1);
         }
    
      if (argc < 3)
        out_stream = stdout;
      else
        if ((out_stream=fopen(argv[2], "w")) == NULL)
         {
          fprintf(stderr, "wav2dat: Can't open output file '%s'.\n", argv[2]);
          return(1);
         }
    
            /*- - - - - - - - - - - - - - - - - - - - - - - - -*/
    
      if (read_bytes(in_stream, buffer, 8) || (strncmp(buffer, "RIFF", 4) != 0))
       {
        fprintf(stderr, "wav2dat: Not a WAV file.\n");
        exit(1);
       }
      length = char2long(&(buffer[4]));
      if (length < 36)
        fprintf(stderr, "wav2dat: Warning: Bad length in header.\n");
    
      if (read_bytes(in_stream, buffer, 8) || (strncmp(buffer, "WAVEfmt ", 8) != 0))
       {
        fprintf(stderr, "wav2dat: Not a WAV file.\n");
        exit(1);
       }
    
      if (read_bytes(in_stream, buffer, 8))
       {
        fprintf(stderr, "wav2dat: Corrupted header.\n");
        exit(1);
       }
      length = char2long(buffer);
      channels = buffer[6];
      if ((channels < 1) || (channels > 4))
       {
        fprintf(stderr, "wav2dat: Bad number of channels (%d).\n", channels);
        exit(1);
       }
    
      if (read_bytes(in_stream, buffer, 12))
       {
        fprintf(stderr, "wav2dat: Corrupted header.\n");
        exit(1);
       }
      freq = char2long(buffer);
      bits_per_sample = buffer[10];
      if ((bits_per_sample != 8) && (bits_per_sample != 16))
       {
        fprintf(stderr, "wav2dat: Unsupported bits/sample (%d).\n", bits_per_sample);
        exit(1);
       }
    
      if (length > 16)
        if (fseek(in_stream, length-16, SEEK_CUR) != 0)
         {
          fprintf(stderr, "wav2dat: Corrupted header.\n");
          exit(1);
         }
    
      do
       {
        if (read_bytes(in_stream, buffer, 8))
         {
          fprintf(stderr, "wav2dat: Corrupted header.\n");
          exit(1);
         }
        length = char2long(&(buffer[4]));
        if (strncmp(buffer, "data", 4) != 0)
          if (fseek(in_stream, length, SEEK_CUR) != 0)
           {
            fprintf(stderr, "wav2dat: Corrupted header.\n");
            exit(1);
           }
       }
      while (strncmp(buffer, "data", 4) != 0);
    
      samples = length / channels * 8 / bits_per_sample;
    
      if (channels == 1)
        fprintf(stderr, "%ld samples, %ld Hz, mono, %d bits/sample.\n",
                samples, freq, bits_per_sample);
      else
        fprintf(stderr, "%ld samples, %ld Hz, %d channels, %d bits/sample.\n",
                samples, freq, channels, bits_per_sample);
    
    /* Jetzt kommen die eigentlichen Audio-Daten... */
    

    (Den Teil mit der Funktion read_bytes() hätte man auch eleganter lösen können... Ist halt schon etwas älter der Quelltext.)



  • Danke, Martin!


Anmelden zum Antworten