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.