/*-------------- Telecommunications & Signal Processing Lab --------------- McGill University Routine: int AOsetDFormat (int Fformat, const int Dformat[], int Nf) Purpose: Determine a compatible data format Description: This routine finds a data format that is compatible with a number of input data formats and a file type. An output file data format compatible with the output file type and the input data formats is found. For multiple input data types, the basic rule is to choose an output data format with at least the same precision. Parameters: <- int AOsetDFormat File type and data format. The file type is the same as that for Fformat. If the data format component of Fformat is specified, that data format is used. Otherwise, the data format is determined by the input data formats. -> int Fformat File type and data format -> const int Dformat[] Input data formats (Nf values) -> int Nf Number of input data formats Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.7 $ $Date: 1996/08/20 16:01:29 $ -------------------------------------------------------------------------*/ static char rcsid[] = "$Id: AOsetDFormat.c 1.7 1996/08/20 AFsp-V2R1 $"; #include /* defines AFILE, used by AFpar.h */ #include #include "AO.h" #define MAXV(a, b) (((a) > (b)) ? (a) : (b)) static const char *DataFormat[NFD] = { "undefined", "mu-law8", "A-law8", "unsigned8", "integer8", "integer16", "float32", "text" }; /* Conversion tables to allowable data formats for different file types */ static int Allow_AFsp[NFD] = { FD_UNDEF, FD_MULAW8, FD_ALAW8, FD_INT8, FD_INT8, FD_INT16, FD_FLOAT32, FD_INT16}; static int Allow_Wave[NFD] = { FD_UNDEF, FD_MULAW8, FD_ALAW8, FD_UINT8, FD_UINT8, FD_INT16, FD_INT16, FD_INT16}; static int Allow_AIFF_C[NFD] = { FD_UNDEF, FD_MULAW8, FD_ALAW8, FD_INT8, FD_INT8, FD_INT16, FD_INT16, FD_INT16}; static int Allow_NH[NFD] = { FD_UNDEF, FD_MULAW8, FD_ALAW8, FD_UINT8, FD_INT8, FD_INT16, FD_FLOAT32, FD_TEXT}; /* Resulting precision for mixed data formats */ /* 0 - undefined, 1 - 16-bit, 2 - float */ static int Prec[NFD] = { 0, 1, 1, 1, 1, 1, 2, 1}; /* Canonical data formats for each of the precisions */ static int DfPrec[3] = {FD_UNDEF, FD_INT16, FD_FLOAT32}; int AOsetDFormat (Fformat, Dformat, Nf) int Fformat; const int Dformat[]; int Nf; { int *Allow; int Ftype, i, Df, Dfr; char *Prog; /* Find the file type and data format from Fformat */ Dfr = Fformat % FW_MOD; Ftype = Fformat - Dfr; /* Find the list of allowed output data types */ if (Ftype == FW_AFSP) Allow = Allow_AFsp; else if (Ftype == FW_WAVE) Allow = Allow_Wave; else if (Ftype == FW_AIFF_C) Allow = Allow_AIFF_C; else Allow = Allow_NH; if (Dfr == FD_UNDEF) { /* Choose the output data type based on the input data types */ /* Data promotion rules - convert to allowable data formats for the output file type - for mixed input formats, find the resulting precision - find the canonical data format for that precision */ for (i = 0; i < Nf; ++i) { Df = Allow[Dformat[i]]; if (i > 0 && Df != Dfr) Dfr = DfPrec[MAXV (Prec[Df], Prec[Dfr])]; else Dfr = Df; } } /* Check the selected data type and change it if it is invalid */ else if (Dfr != Allow[Dfr]) { Dfr = Allow[Dfr]; Prog = UTgetProg (); if (Prog[0] == '\0') Prog = "AOsetDFormat"; UTwarn ("%s - Invalid output file data format, using \"%s\"", UTgetProg (), DataFormat[Dfr]); } return (Dfr + Ftype); }