Logo Search packages:      
Sourcecode: nas version File versions  Download package

8svx.c

/*
 * Copyright 1993 Network Computing Devices, Inc.
 * 
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name Network Computing Devices, Inc. not be
 * used in advertising or publicity pertaining to distribution of this
 * software without specific, written prior permission.
 * 
 * THIS SOFTWARE IS PROVIDED 'AS-IS'.  NETWORK COMPUTING DEVICES, INC.,
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
 * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NONINFRINGEMENT.  IN NO EVENT SHALL NETWORK
 * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
 * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
 * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
 * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 * $NCDId: @(#)8svx.c,v 1.6 1995/12/06 01:22:09 greg Exp $
 */

#include "config.h"

#include <stdio.h>

#if defined(HAVE_STDLIB_H)
# include <stdlib.h> 
#endif

#if defined(HAVE_MALLOC_H)
# include <malloc.h>
#endif


#include <audio/Aos.h>
#include <math.h>
#include <audio/8svx.h>
#include <audio/fileutil.h>

#define Err()           { SvxCloseFile(si); return NULL; }
#define readID(_f)      fread(_f, sizeof(SVX_ID), 1, si->fp)
#define readByte(_f)    fread(_f, 1, 1, si->fp)
#define cmpID(_x, _y)   strncmp((char *) (_x), (char *) (_y), sizeof(SVX_ID))

static int
readChunk(SvxChunk *c, FILE *fp)
{
    int             status;
    char            n;

    if ((status = fread(c, sizeof(SvxChunk), 1, fp)))
      if (NAS_LITTLE_ENDIAN)
          swapl(&c->ckSize, n);

    return status;
}

SvxInfo        *
SvxOpenFileForReading(_SvxConst char *name)
{
    SvxInfo        *si;
    SvxChunk        ck;
    SVX_ID          id;
    AuInt32         fileSize;

    if (!(si = (SvxInfo *) malloc(sizeof(SvxInfo))))
      return NULL;

    si->comment = NULL;
    si->dataOffset = si->writing = 0;

    if (!(si->fp = fopen(name, AU_READ_BINARY)))
      Err();

    if (!readChunk(&ck, si->fp) ||
      cmpID(&ck.ckID, SVX_FormID) ||
      !readID(&id) ||
      cmpID(&id, SVX_8svxID))
      Err();

    fileSize = ck.ckSize - sizeof(SVX_ID);

    while (fileSize > sizeof(SvxChunk))
    {
      if (!readChunk(&ck, si->fp))
          Err();

      fileSize -= sizeof(SvxChunk) + ck.ckSize;

      /* Voice8Header chunk */
      if (!cmpID(&ck.ckID, SVX_VhdrID))
      {
          AuUint8         c;

          si->numSamples = FileReadL(si->fp, NAS_LITTLE_ENDIAN);
          FileReadL(si->fp, NAS_LITTLE_ENDIAN);
          FileReadL(si->fp, NAS_LITTLE_ENDIAN);
          si->sampleRate = FileReadS(si->fp, NAS_LITTLE_ENDIAN);
          readByte(&c);
          readByte(&c);

          if (c)
            Err();

          FileReadL(si->fp, NAS_LITTLE_ENDIAN);
      }
      /* sound data chunk */
      else if (!cmpID(&ck.ckID, SVX_BodyID))
      {
          si->dataOffset = ftell(si->fp);
          si->dataSize = ck.ckSize;

          /* seek past the data */
          fseek(si->fp, ck.ckSize, 1);
      }
      /* NAME chunk */
      else if (!cmpID(&ck.ckID, SVX_NameID))
      {
          if (!(si->comment = (char *) malloc(ck.ckSize + 1)) ||
            !fread(si->comment, ck.ckSize, 1, si->fp))
            Err();

          si->comment[ck.ckSize] = 0;
      }
      else
          /* skip unknown chunk */
          fseek(si->fp, ck.ckSize, 1);
    }

    if (!si->dataOffset)
      Err();

    si->numSamples = si->dataSize;

    if (!si->comment)
      si->comment = FileCommentFromFilename(name);

    SvxRewindFile(si);
    return si;
}

SvxInfo *
SvxOpenFileForWriting(_SvxConst char *name, SvxInfo *si)
{
    int             n;

    si->writing = si->dataSize = 0;

    if (!(si->fp = fopen(name, AU_WRITE_BINARY)) ||
      !fwrite(SVX_FormID, sizeof(SVX_ID), 1, si->fp))
      Err();

    si->sizeOffset = ftell(si->fp);

    if (!FileWriteL(0, si->fp, NAS_LITTLE_ENDIAN) ||
      !fwrite(SVX_8svxID, sizeof(SVX_ID), 1, si->fp))
      Err();

    si->fileSize = sizeof(SVX_ID);

    if ((n = strlen(si->comment)))
    {
      if (!fwrite(SVX_NameID, sizeof(SVX_ID), 1, si->fp) ||
          !FileWriteL(n, si->fp, NAS_LITTLE_ENDIAN) ||
          !fwrite(si->comment, n, 1, si->fp))
          Err();

      si->fileSize += sizeof(SvxChunk) + n;
    }

    if (!fwrite(SVX_VhdrID, sizeof(SVX_ID), 1, si->fp) ||
      !FileWriteL(SVX_SizeofVhdrChunk, si->fp, NAS_LITTLE_ENDIAN) ||
      !FileWriteL(si->numSamples, si->fp, NAS_LITTLE_ENDIAN) ||
      !FileWriteL(0, si->fp, NAS_LITTLE_ENDIAN) ||
      !FileWriteL(0, si->fp, NAS_LITTLE_ENDIAN) ||
      !FileWriteS(si->sampleRate, si->fp, NAS_LITTLE_ENDIAN) ||
      !FileWriteS(0, si->fp, NAS_LITTLE_ENDIAN) ||
      !FileWriteL(SVX_MaxVolume, si->fp, NAS_LITTLE_ENDIAN))
      Err();

    si->fileSize += sizeof(SvxChunk) + SVX_SizeofVhdrChunk;

    if (!fwrite(SVX_BodyID, sizeof(SVX_ID), 1, si->fp))
      Err();

    si->dataOffset = ftell(si->fp);

    if (!FileWriteL(0, si->fp, NAS_LITTLE_ENDIAN))
      Err();

    si->fileSize += sizeof(SvxChunk);

    si->writing = 1;
    return si;
}

int
SvxCloseFile(SvxInfo *si)
{
    int             status = 0;

    if (si->fp)
    {
      if (si->writing)
      {
          fseek(si->fp, si->sizeOffset, 0);
          FileWriteL(si->fileSize + si->dataSize, si->fp, NAS_LITTLE_ENDIAN);
          fseek(si->fp, si->dataOffset, 0);
          FileWriteL(si->dataSize, si->fp, NAS_LITTLE_ENDIAN);
      }

      status = fclose(si->fp);
    }

    if (si->comment)
      free(si->comment);

    free(si);
    return status;
}

int
SvxReadFile(char *p, int n, SvxInfo *si)
{
    return fread(p, 1, n, si->fp);
}

int
SvxWriteFile(char *p, int n, SvxInfo *si)
{
    int             num;

    num = fwrite(p, 1, n, si->fp);
    si->dataSize += num;
    return num;
}

int
SvxRewindFile(SvxInfo *si)
{
    return si->writing ? -1 : fseek(si->fp, si->dataOffset + sizeof(long), 0);
}

int
SvxSeekFile(int n, SvxInfo *si)
{
    return si->writing ? -1 :
      fseek(si->fp, si->dataOffset + sizeof(long) + n, 0);
}

int
SvxTellFile(SvxInfo *si)
{
    return si->writing ? -1 :
      ftell(si->fp) - si->dataOffset - sizeof(long);
}

int
SvxFlushFile(SvxInfo *si)
{
    return fflush(si->fp);
}

Generated by  Doxygen 1.6.0   Back to index