/* wav.c
 * Copyright (C) 2004, 2005 Sylvain Cresto <scresto@gmail.com>
 *
 * This file is part of graveman!
 *
 * graveman! is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or
 * (at your option) any later version.
 * 
 * graveman! is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with program; see the file COPYING. If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA. 
 * 
 * URL: http://www.nongnu.org/graveman/
 *
 */

#include "graveman.h"

/*
 * gestion du format wav (description dans http://ccrma.stanford.edu/CCRMA/Courses/422/projects/WaveFormat/)
 */

typedef struct {
  gchar riff[4];      /* chaine "RIFF" */
  gulong file_length; /* taille du fichier en bytes - 8 */
  gchar wave[8];      /* chaine "WAVEfmt " */
  gulong offset;      /* position fin entete / debut son */
  gushort format;     /* format: 1 = PCM */
  gushort nchans;     /* nombre de channel (1=mono / 2=stereo) */
  gulong sampsec;     /* rate (eg. 44100) */
  gulong bytesec;     /* bytes/sec, all channels (4=16bit stereo) */
  gushort bytesamp;   /* bytes/sample (2=16bit)*/
  gushort bitsamp;    /* bits/sample par channel (16..) */
  gchar dataheader[4]; /* chaine "data" */
  gulong datalen;     /* longueur donnees */
} T_WAV_format;

/* retourne la duree d'un fichier wav */
gboolean getWavInfo(gchar *Afilename, guint32 *Alength, GError **Aerror)
{
  FILE *Lfic = fopen(Afilename, "rb");
  guint32 LSEC;
  guint32 Ltaille;
/*  gulong Lmin, Lsec; */
  T_WAV_format Lheader;

  *(Alength) = 0;

  if (!Lfic) {
    g_set_error(Aerror, G_FILE_ERROR, g_file_error_from_errno(errno), "%s:%s\n%s",
         _("Cannot read file"), Afilename, strerror(errno));
    return FALSE;
  }

  /* lecture entete fichier wav */
  if (fread(&Lheader, sizeof(Lheader), 1, Lfic) != 1) {
    fclose(Lfic);
    g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA, _("%s is not a valid .wav file !"), Afilename);
    return FALSE;
  }
  fclose(Lfic);

  /* verirication validite de l'entete, a savoir que le champ riff contiene bien RIFF et qu'il
   * y a bien le type WAVEfmt dans wave */
  if (memcmp(Lheader.riff, "RIFF", 4) || memcmp(Lheader.wave, "WAVEfmt ", 8)) {
    g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA, _("%s is not a valid .wav file !"), Afilename);
    return FALSE;
  }

//  LSEC = (gdouble)Lheader.sampsec * Lheader.nchans * Lheader.bitsamp / 8;
  LSEC = Lheader.sampsec * Lheader.nchans * Lheader.bitsamp / 8;
  if (!(Ltaille = Lheader.file_length / LSEC)) Ltaille = 1;

  *(Alength) = Ltaille;

  return TRUE;
}

/*
 * vim:et:ts=8:sts=2:sw=2
 */
