P From:	US1RMC::"seymour@m31.dgbt.doc.ca" "Seymour Shlien" 27-AUG-1993 15:05:31.82 To:	3d::pan  CC:	 Subj:	problems and fixes   Dear Davis,   2 I have now got the MPEG audio coder and decoder to= work on both UNIX (Sparc 2) and Microsoft C. All the problems = that we encountered were mainly restricted to the code in the * file common.c and were related to the AIFF5 audio format functions. I gather from the comments in 8 the text, other people had encountered similar problems.  + When compiled under UNIX,  the gcc compiler ! gave messages similar to below.     * common.c: In function `aiff_read_headers':9 common.c:673: warning: multi-character character constant 9 common.c:674: warning: multi-character character constant 9 common.c:688: warning: multi-character character constant 9 common.c:719: warning: multi-character character constant Z common.c:719: warning: passing arg 2 of `strcmp' makes pointer from integer without a cast+ common.c: In function `aiff_write_headers': 9 common.c:807: warning: multi-character character constant 9 common.c:808: warning: multi-character character constant 9 common.c:809: warning: multi-character character constant   B    670     if (fread(&FormChunk, sizeof(Chunk), 1, file_ptr) != 1)    671        return(-1); 	    672    B    673     if (*(unsigned long *) FormChunk.ckID != IFF_ID_FORM ||D    674         *(unsigned long *) FormChunk.formType != IFF_ID_AIFF)    675        return(-1);     676    6776    678  /*   if (strcmp(FormChunk.ckID,IFF_ID_FORM) ||6    679         strcmp(FormChunk.formType,IFF_ID_AIFF))    680        return(-1); 
    681  */    ...    ...G    715           aiff_ptr->numSampleFrames = CommChunk.numSampleFrames; =    716           aiff_ptr->sampleSize = CommChunk.sampleSize; 	    717    K    718  /*    } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { */ ;    719        } else if (strcmp(Header.ckID,IFF_ID_SSND)) { 	    720        721           /*     5 Similarly on MSDOS we obtained the following warnings   < Microsoft (R) Program Maintenance Utility   Version 1.11    : Copyright (c) Microsoft Corp 1988-90. All rights reserved.  + 	cl /AL /G2 /FPi87 /nologo /c /Gi musicin.c 	 musicin.c F musicin.c(959) : warning C4047: '!=' : different levels of indirection* 	cl /AL /G2 /FPi87 /nologo /c /Gi common.c common.cD common.c(814) : warning C4047: '=' : different levels of indirectionD common.c(815) : warning C4047: '=' : different levels of indirectionD common.c(816) : warning C4047: '=' : different levels of indirection  	    814    ?    815     *(unsigned long *) FormChunk.ckID     = IFF_ID_FORM; ?    816     *(unsigned long *) FormChunk.formType = IFF_ID_AIFF; ?    817     *(unsigned long *) CommChunk.ckID     = IFF_ID_COMM;     818F    819     double_to_extended(&aiff_ptr->sampleRate, temp_sampleRate);   = also a few similar error messages in musicin.c and musicout.c     A Despite these warnings both the encoder (musicin) and the decoder 5 musicout appeared to run correctly on the data files  8 orig.mpg and sine.dec. However command line input is not> properly implemented on MicroSoft C. The program tries to make/ a file orig.mpg.dec which is not legal in MSDOS                 BUGS  IN THE SOFTWARE  ) For MS_DOS it was necessary to modify the F mem_alloc function in order to avoid crashing the computer on startup.> I do not know the reason as I am not an expert in MicroSoft C.    A Also, the software does not properly handle AIFF formatted files. @ Using the program musicout I created an AIFF formatted file fromC the orig.mpg file. When I ran musicin on the AIFF formatted file on A our SUN work station (ie UNIX environment) , the program crashed. A On the other hand, when the same test was performed on the MSDOS, 9 the computer did not crash but it failed to recognize the D file as an AIFF formatted file and it did not read the header block.I Nevertheless it was still able to compress the file, once the appropriate ! header information was typed in.      E The problems seem to be related to the handling of the ID information F in the chunk structure of the AIFF file. The ID is a 32 bit integer   @ which can take one of 5 designated values. The designated values? for convenience also can be decoded as ascii strings FORM, AIFF B COMM, SSND and MPEG. The ISO software attempts to provide two waysA of handling these numbers- either as a multicharacter constant or 	 a string.    In the common.h file   /*1  * Note:  The value of a multi-character constant $  *        is implementation-defined.  */ % #if !defined(MS_DOS) && !defined(AIX)   . #define         IFF_ID_FORM             'FORM'. #define         IFF_ID_AIFF             'AIFF'. #define         IFF_ID_COMM             'COMM'. #define         IFF_ID_SSND             'SSND'. #define         IFF_ID_MPEG             'MPEG' #else . #define         IFF_ID_FORM             "FORM". #define         IFF_ID_AIFF             "AIFF". #define         IFF_ID_COMM             "COMM". #define         IFF_ID_SSND             "SSND". #define         IFF_ID_MPEG             "MPEG" #endif       4 Unfortunately, the revisions to the code in common.c6 do not properly read or write the AIFF header block in either mode.  9 If the IFF_* constants are defined as a long integer, (ie 7 single quotes around FORM, AIFF, etc.), then the strcmp 7 function will crash on some machines because the inputs 3 Header.ckID and IFF_ID_FORM are not strings. Strcmp 4 expects to receive null terminated strings. Since it8 instead receives addresses to nonterminated strings, the= strcmp runs off to infinity searching for the null character.   7 Note: when IFF_* are defined as strings, Header.ckID is 6 still not a null terminated string. Fortunately strcmp6 stops when a null is encountered in either one of its 2 arguments -- in this case a null is encountered in6 IFF_*. It might be safer to use strncmp which includes a string length argument.        9 This was the source of our problem on the UNIX machine as 4 the common.c attempted to do a string compare in one spot (around line 718).   C /*    } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { */ 3       } else if (strcmp(Header.ckID,IFF_ID_SSND)) {   5 The commented line would have worked correctly in the  UNIX environment.     6 A different problem occurs in MS_DOS. In the function : aiff_write_header the following statement does not do what* was intended when IFF_ID_FORM is a string.  6   *(unsigned long *) FormChunk.ckID     = IFF_ID_FORM;  = IFF_ID_FORM points to an address of the string "FORM". Though : it was intended to put "FORM" in FormChunk.ckID, the above8 statement instead places the address of IFF_ID_FORM into= FormChunk.ckID. This is what is put in the AIFF file. Musicin > reads the file and fails to recognize it as an AIFF file. (The: above statement would have been correct if IFF_ID_FORM was a long integer.)                      FIXES  < I have made the following changes in the software so that it< can now handle AIFF formatted files in either MicroSoft C or UNIX.   8 In common.h, I have introduced a new def called IFF_LONG= whenever IFF_* is represented by multicharacter longs instead  of strings.     187,188c187 ) < #if !defined(MS_DOS) && !defined(AIX)    < #define         IFF_LONG --- ' > #if !defined(MS_DOS) && !defined(AIX)         + In common.c the following changes were made     ' For avoiding crashing the PC on startup  456,457c456 Y <     /*ptr = (void FAR *) _fmalloc((unsigned int)block);*/ /* far memory, 92-07-08 sr */ S <     ptr = (void FAR *) malloc((unsigned int)block); /* far memory, 93-08-24 ss */  --- U >     ptr = (void FAR *) _fmalloc((unsigned int)block); /* far memory, 92-07-08 sr */         For debugging and testing  646,656d644  <  < /****  for debugging   < showchar(str)  < char str[4]; < {  < int i;( < for (i=0;i<4;i++) printf("%c",str[i]); < printf("\n");  < }  < ****/  <     0 To correct the problems with the IFF_* ID's I do3 the string comparisons two different ways depending   on whether IFF_LONG is defined.        685d672  < #ifdef IFF_LONG  689d675  < #else  691,694d676 1 <    if (strncmp(FormChunk.ckID,IFF_ID_FORM,4) ||R3 <        strncmp(FormChunk.formType,IFF_ID_AIFF,4))- <       return(-1);	 < #endif 695a678,681r0 > /*   if (strcmp(FormChunk.ckID,IFF_ID_FORM) ||0 >        strcmp(FormChunk.formType,IFF_ID_AIFF)) >       return(-1);i > */ 702d687t < #ifdef IFF_LONG    705,708c690,691m < #elset6 <       if (strncmp(Header.ckID,IFF_ID_COMM,4) == 0) { < #endif <  ---i0 > /*      if (strcmp(Header.ckID,IFF_ID_COMM)) { > */ 711a695e >  734,738c718,720r < #ifdef IFF_LONG C <       } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { a < #elsew= <       } else if (strncmp(Header.ckID,IFF_ID_SSND,4) == 0) {3 < #endif ---iE > /*    } else if (*(unsigned long *)Header.ckID == IFF_ID_SSND) { */c5 >       } else if (strcmp(Header.ckID,IFF_ID_SSND)) {t >  741a724c >  824d806m < #ifdef IFF_LONG  828,832d809r < #elser+ <    strncpy(FormChunk.ckID,IFF_ID_FORM,4);g/ <    strncpy(FormChunk.formType,IFF_ID_AIFF,4); + <    strncpy(CommChunk.ckID,IFF_ID_COMM,4);d < #endif	 1536a1514  >          In musicin.c  E The following changes were made for the same reasons discussed above.t     959d958c < #ifdef IFF_LONGi 961,963d959a < #elsen> <     if (strncmp(&pcm_aiff_data->sampleType,IFF_ID_SSND,4)) { < #endif      
 In musicout.cu  E The following changes were made for the same reasons discussed above.      381d380| < #ifdef IFF_LONG        383,385d381m < #elsem: <        strncpy(&pcm_aiff_data.sampleType,IFF_ID_SSND,4); < #endif 388c384i <  r ---o >     B This is a copy of the makefile that I am using on the IBM. Perhaps= one of the switches might explain why I had trouble with the .
 mem_alloc.   ALL : musicin.exe musicout.exe  . CFLAGS = /AL /G2 /FPi87 /nologo /c /Gi /F 256 # LFLAGS= /SE:256 /ST:16000 /F /PACKCi  ) musicin.obj: musicin.c common.h encoder.hu     cl $(CFLAGS) musicin.c   common.obj: common.c common.h      cl $(CFLAGS) common.cc  ' encode.obj: encode.c common.h encoder.h      cl $(CFLAGS) encode.cn  # subs.obj: subs.c common.h encoder.hg     cl $(CFLAGS) subs.ca  ! psy.obj: psy.c common.h encoder.h      cl $(CFLAGS) psy.c  % tonal.obj: tonal.c common.h encoder.h      cl $(CFLAGS) tonal.c  + musicout.obj: musicout.c common.h decoder.h:     cl $(CFLAGS) musicout.ce  ' decode.obj: decode.c common.h decoder.h7     cl $(CFLAGS) decode.co  I musicin.exe: musicin.obj common.obj encode.obj subs.obj psy.obj tonal.obj B     link $(LFLAGS) musicin common encode subs psy tonal,musicin,,;  9 musicout.exe: musicout.obj common.obj decode.obj subs.objd:     link $(LFLAGS) musicout common decode subs,musicout,,;        H I am grateful, for the help from Daniel Lauzon -- our resident C and C++7 expert. Also Bill Truerniet helped me with Microsoft C D
 on the PC.    M   seymour@dgbt.doc.cad    H % ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======K % Received: by us1rmc.bb.dec.com; id AA06920; Fri, 27 Aug 93 14:58:09 -0400bN % Received: by inet-gw-1.pa.dec.com; id AA02547; Fri, 27 Aug 93 11:59:18 -0700k % Received: from rigel.dgbt.doc.ca by  m31.dgbt.doc.ca (4.1/SMI-4.1) id AA01692; Fri, 27 Aug 93 14:57:59 EDf# % Date: Fri, 27 Aug 93 14:57:59 EDTe0 % From: seymour@m31.dgbt.doc.ca (Seymour Shlien)3 % Message-Id: <9308271857.AA01692@ m31.dgbt.doc.ca>e
 % To: 3d::panf % Subject: problems and fixesr 