ftp.nice.ch/pub/next/unix/communication/am.1.16.NIHS.bs.tar.gz#/am.1.16.NIHS.bs/src/snd2zyxel.c

This is snd2zyxel.c in view mode; [Download] [Up]

/* NeXT snd to Zyxel-voice file converter

   Convert (stdio) sound-files to zyxel (stdout).

   Copyright 1994 (C) Thomas Funke.
   

*/   

#import <sound/sound.h>
#import <sound/convertsound.h>

#import "precomp.h"


typedef unsigned char uchar;

uchar
lin16_to_ad2 (short a)					//convert 16bit value to 2bit
{
    static short a0 = 0;
    static uchar e;
    static int D = 5; //Delta
    float   E;
    static int M[] = {0x3800, 0x5600};

    E = (a - a0) / (float) D;

    if (E < 0) {
	if (E < -1.5)
	    e = 3;
	else
	    e = 2;
    } else {
	if (E > 1.5)
	    e = 1;
	else
	    e = 0;
    }
	    	    

    D = D * M[e & 1];
    D += 0x2000;
    D >>= 14;    //div 16384
    if (D < 5)
	D = 5;

    a0 = a;
    return e;	
}


void write_zyxel (void)
// write to stdout zyxel-data
{
    struct zyxel header = {0};
    short *p;
    char *pend;
    int err;
    

    SNDSoundStruct *sndp1, *sndp2;
    SNDSoundStruct snd;
    

    if ((err=SNDRead (0, &sndp1)) != SND_ERR_NONE) {
	fprintf (stderr, "Error reading sound file: %s\n",
	    SNDSoundError(err));
	exit (1);
    }
    

    // Convert Sound to 9600 / lin / mono
    

    snd.magic = SND_MAGIC;
    snd.dataLocation = sizeof (SNDSoundStruct);
    snd.dataSize = 0;
    snd.dataFormat = SND_FORMAT_LINEAR_16;
    snd.samplingRate = 9600;
    snd.channelCount = 1;
    sndp2 = &snd;
    

    if ((err=SNDConvertSound (sndp1, &sndp2)) != SND_ERR_NONE) {
	fprintf (stderr, "Error converting sound: %s\n", 

	    SNDSoundError(err));
	exit (1);
    }
    

    

    // Write Zyxel header
    strncpy ((char*)&header.title, "ZyXEL", sizeof(header.title));
    header.mode = ZYX_VOC;
    header.voice = ZYX_AD2; // 2 bit ADPCM
    fwrite (&header, sizeof(header), 1, stdout);
    


    // start loop 

    p = (void *) sndp2 + sndp2->dataLocation;
    pend = (void *) sndp2 + sndp2->dataSize - 6;

    while ((char *) p < pend) {
	short in[4];
	uchar out;
        

	in[0] = *p++;
	in[1] = *p++;
	in[2] = *p++;
	in[3] = *p++;

	out = (lin16_to_ad2 (in[0]) << 6) +
	      (lin16_to_ad2 (in[1]) << 4) +
	      (lin16_to_ad2 (in[2]) << 2) +
	      (lin16_to_ad2 (in[3]));
	fwrite (&out, 1, 1, stdout);
	if (out == 0x10)
	    fwrite (&out, 1, 1, stdout); // double DLE 

    }

}

int main ()
{
    write_zyxel ();
    return 0;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.