This is snd2zsnd.c in view mode; [Download] [Up]
/*********************************************************************/ /* */ /* Programmer: */ /* Olaf Mueller <olaf@orest.escape.de> */ /* */ /* Purpose: */ /* Answering Machine */ /* converting NeXT sound to ZyXEL voice */ /* */ /* History: */ /* 29-08-96 Initial Release Olaf Mueller */ /* */ /* Notes: */ /* I confess, i have no idea what I am programming here. */ /* The Zyxel algorithm is completeley unknown for me. */ /* This code is a result of reverse engineering of the old */ /* am.1.16 code. */ /* Probably it is full of errors, but who cares. It works for me */ /* Olaf */ /* */ /*********************************************************************/ #include "zyxel.h" static unsigned char lin16_to_ad2 (short dataWord) { int M [] = { 0x3800 , 0x5600 } ; static int delta = 5 ; static short val = 0 ; char signBit = 0 ; unsigned char dataByte ; int E ; E = (2 * (dataWord - val)) / delta ; val = dataWord ; if (E < 0) { signBit = 0x02 ; E = -E ; } if (E > 3) dataByte = 0x01 ; else dataByte = 0x00 ; delta = (M [dataByte] * delta + 0x2000) >> 14 ; if (delta < 5) delta = 5 ; return signBit | dataByte ; } static unsigned char lin16_to_ad3 (short dataWord) { int M [] = { 0x399A , 0x3A9F , 0x4D14 , 0x6607 } ; static int delta = 5 ; static short val = 0 ; char signBit = 0 ; unsigned char dataByte ; int E ; E = (2 * (dataWord - val)) / delta ; if (E < 0) { signBit = 0x04 ; E = -E ; } if (E > 6) dataByte = 0x03 ; else if (E > 4) dataByte = 0x02 ; else if (E > 2) dataByte = 0x01 ; else dataByte = 0x00 ; if ((delta & 1) && !signBit) ++val ; if (!signBit) val += dataByte * delta + delta >> 1 ; else val -= dataByte * delta + delta >> 1 ; delta = (M [dataByte] * delta + 0x2000) >> 14 ; if (delta < 5) delta = 5 ; return signBit | dataByte ; } #include <libc.h> #import <sound/sound.h> static void snd_to_ad2 (SNDSoundStruct *snd,FILE *fpzsnd) { short sndsample ; short *sounddata ; long soundcount ; int icnt = 4 ; unsigned char zbyte = 0 ; sounddata = (short*) ((char*)snd + snd->dataLocation) ; soundcount = snd->dataSize / 2 ; while (soundcount--) { sndsample = NXSwapBigShortToHost (*sounddata++) ; switch (icnt) { case 4: zbyte = lin16_to_ad2 (sndsample) << 6 ; break ; case 3: zbyte |= lin16_to_ad2 (sndsample) << 4 ; break ; case 2: zbyte |= lin16_to_ad2 (sndsample) << 2 ; break ; case 1: zbyte |= lin16_to_ad2 (sndsample) ; fwrite (&zbyte,sizeof(unsigned char),1,fpzsnd) ; break ; } if (--icnt == 0) icnt = 4 ; } } static void snd_to_ad3 (SNDSoundStruct *snd,FILE *fpzsnd) { short sndsample ; short *sounddata ; long soundcount ; int icnt = 8 , restbyte = 0 ; unsigned char zbyte = 0 ; sounddata = (short*) ((char*)snd + snd->dataLocation) ; soundcount = snd->dataSize / 2 ; while (soundcount--) { sndsample = NXSwapBigShortToHost (*sounddata++) ; switch (icnt) { case 8: zbyte = lin16_to_ad3 (sndsample) << 5 ; break ; case 7: zbyte |= lin16_to_ad3 (sndsample) << 2 ; break ; case 6: restbyte = lin16_to_ad3 (sndsample) ; zbyte |= restbyte >> 1 ; fwrite (&zbyte,sizeof(unsigned char),1,fpzsnd) ; zbyte = restbyte << 7 ; break ; case 5: zbyte |= lin16_to_ad3 (sndsample) << 4 ; break ; case 4: zbyte |= lin16_to_ad3 (sndsample) << 1 ; break ; case 3: restbyte = lin16_to_ad3 (sndsample) ; zbyte |= restbyte >> 2 ; fwrite (&zbyte,sizeof(unsigned char),1,fpzsnd) ; zbyte = restbyte << 6 ; break ; case 2: zbyte |= lin16_to_ad3 (sndsample) << 3 ; break ; case 1: zbyte |= lin16_to_ad3 (sndsample) ; fwrite (&zbyte,sizeof(unsigned char),1,fpzsnd) ; break ; } if (--icnt == 0) icnt = 8 ; } } static void PrintUsage (void) { printf ("usage: snd2zsnd [-h] [-f <Zyxel_format>] <NeXT_sound_file> <Zyxel_voice_file>\n") ; printf (" Zyxel_format: 2 = ADPCM3 (default)\n") ; printf (" 1 = ADPCM2\n") ; } int main (int argc,char *argv[]) { int opt , optFormat = ZYX_AD3 ; SNDSoundStruct *sndp , *sndpc , snd ; int err ; ZyxelHeader zyxhead = { 0 } ; FILE *fpzsnd ; /***** ***** we scan options and parameters *****/ while ((opt = getopt(argc,argv,"hf:")) != -1) { switch (opt) { case 'f': optFormat = atoi (optarg) ; if (optFormat != ZYX_AD3 && optFormat != ZYX_AD2) { PrintUsage () ; return 1 ; } break ; case 'h': PrintUsage () ; return 2 ; case '?' : return 1 ; } } if (argc - optind != 2) { PrintUsage () ; return 2 ; } if ((err = SNDReadSoundfile(argv[optind],&sndp)) != SND_ERR_NONE) { printf ("Error reading sound file: %s\n",SNDSoundError(err)) ; return 1 ; } snd.magic = SND_MAGIC; snd.dataFormat = SND_FORMAT_LINEAR_16 ; snd.samplingRate = 9600 ; snd.channelCount = 1 ; sndpc = &snd ; if ((err = SNDConvertSound(sndp,&sndpc)) != SND_ERR_NONE) { printf ("Error converting sound file: %s\n",SNDSoundError(err)) ; return 1 ; } SNDFree (sndp) ; memcpy (zyxhead.title,ZYX_TITLE,strlen(ZYX_TITLE)) ; zyxhead.mode = ZYX_VOC ; zyxhead.voice = optFormat ; fpzsnd = fopen (argv[optind+1],"w") ; fwrite (&zyxhead,sizeof(ZyxelHeader),1,fpzsnd) ; switch (optFormat) { case ZYX_AD3: snd_to_ad3 (sndpc,fpzsnd) ; break ; case ZYX_AD2: snd_to_ad2 (sndpc,fpzsnd) ; break ; } fclose (fpzsnd) ; return 0 ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.