mirror of
https://github.com/thestk/stk
synced 2026-01-11 20:11:52 +00:00
169 lines
3.7 KiB
C++
169 lines
3.7 KiB
C++
/*******************************************/
|
|
/* NeXT Sound File Output Class, */
|
|
/* by Perry R. Cook, 1995-96 */
|
|
/* This version opens a mono NeXT .snd */
|
|
/* file 16bit data at 22KHz, and */
|
|
/* pokes buffers of samples into it. */
|
|
/*******************************************/
|
|
|
|
/*******************************************/
|
|
/* NeXT Soundfile Output Class, Improved */
|
|
/* by Perry R. Cook, 1996 */
|
|
/* This one opens a NeXT .snd file, and */
|
|
/* even knows how to byte-swap! */
|
|
/*******************************************/
|
|
|
|
#include "SndWvOut.h"
|
|
|
|
#ifdef __LITTLE_ENDIAN__
|
|
#include "swapstuf.h"
|
|
#endif
|
|
|
|
/******** NeXT Soundfile Header Struct *******/
|
|
struct headerform {
|
|
char pref[4];
|
|
long hdr_length;
|
|
long file_length;
|
|
long mode;
|
|
long samp_rate;
|
|
long num_channels;
|
|
char comment[16];
|
|
};
|
|
|
|
FILE *openNeXTFile(int chans,char *fileName) {
|
|
struct headerform hdr = {".sn",40,0,3,(long) SRATE,1,"STK98"};
|
|
char tempName[128];
|
|
FILE *fd;
|
|
|
|
hdr.pref[3] = 'd';
|
|
|
|
strcpy(tempName,fileName);
|
|
strcat(tempName,".snd");
|
|
hdr.num_channels = chans;
|
|
fd = fopen(tempName,"wb");
|
|
if (!fd) {
|
|
printf("Couldn't create soundfile %s !!!!!!!!\n",fileName);
|
|
exit(0);
|
|
}
|
|
#ifdef __LITTLE_ENDIAN__
|
|
hdr.hdr_length = SwapInt (hdr.hdr_length);
|
|
hdr.file_length = SwapInt (hdr.file_length);
|
|
hdr.mode = SwapInt (hdr.mode);
|
|
hdr.samp_rate = SwapInt (hdr.samp_rate);
|
|
hdr.num_channels = SwapInt (hdr.num_channels);
|
|
#endif
|
|
printf("Creating soundfile %s.\n", tempName);
|
|
fwrite(&hdr,4,10,fd);
|
|
return fd;
|
|
}
|
|
|
|
SndWvOut :: SndWvOut(char *fileName)
|
|
{
|
|
chans = 1;
|
|
pan = 0.5;
|
|
fd = openNeXTFile(chans,fileName);
|
|
counter = 0;
|
|
totalCount = 0;
|
|
}
|
|
|
|
SndWvOut :: SndWvOut(int channels, char *fileName)
|
|
{
|
|
chans = channels;
|
|
pan = 0.5;
|
|
fd = openNeXTFile(chans,fileName);
|
|
counter = 0;
|
|
totalCount = 0;
|
|
}
|
|
|
|
SndWvOut :: ~SndWvOut()
|
|
{
|
|
double temp;
|
|
|
|
fwrite(data,2,counter,fd);
|
|
fseek(fd,8,SEEK_SET);
|
|
temp = (double) totalCount * ONE_OVER_SRATE;
|
|
printf("%f Seconds Computed\n",temp);
|
|
totalCount *= 2*chans;
|
|
#ifdef __LITTLE_ENDIAN__
|
|
totalCount = SwapInt (totalCount);
|
|
#endif
|
|
fwrite(&totalCount,4,1,fd);
|
|
fclose(fd);
|
|
}
|
|
|
|
long SndWvOut :: getCounter()
|
|
{
|
|
return totalCount;
|
|
}
|
|
|
|
MY_FLOAT SndWvOut :: getTime()
|
|
{
|
|
return (MY_FLOAT) totalCount * ONE_OVER_SRATE;
|
|
}
|
|
|
|
void SndWvOut :: tick(MY_FLOAT sample)
|
|
{
|
|
short isample;
|
|
|
|
isample = (short) (sample * 32000.0);
|
|
if (chans==1) {
|
|
data[counter] = isample;
|
|
#ifdef __LITTLE_ENDIAN__
|
|
data[counter] = SwapShort (data[counter]);
|
|
#endif
|
|
counter += 1;
|
|
}
|
|
else {
|
|
data[counter] = (short) (isample * (1.0 - pan));
|
|
data[counter+1] = (short) (isample * pan);
|
|
#ifdef __LITTLE_ENDIAN__
|
|
data[counter] = SwapShort (data[counter]);
|
|
data[counter+1] = SwapShort (data[counter+1]);
|
|
#endif
|
|
counter += 2;
|
|
}
|
|
totalCount += 1;
|
|
if (counter == SND_BUFFER_SIZE) {
|
|
fwrite(data,2,SND_BUFFER_SIZE,fd);
|
|
counter = 0;
|
|
}
|
|
}
|
|
|
|
void SndWvOut :: tick(MY_FLOAT lsamp, MY_FLOAT rsamp)
|
|
{
|
|
if (chans==1) {
|
|
data[counter] = (short) ((lsamp + rsamp) * 16000.0);
|
|
#ifdef __LITTLE_ENDIAN__
|
|
data[counter] = SwapShort (data[counter]);
|
|
#endif
|
|
counter += 1;
|
|
}
|
|
else {
|
|
data[counter] = (short) (lsamp * 32000.0);
|
|
data[counter+1] = (short) (rsamp * 32000.0);
|
|
#ifdef __LITTLE_ENDIAN__
|
|
data[counter] = SwapShort (data[counter]);
|
|
data[counter+1] = SwapShort (data[counter+1]);
|
|
#endif
|
|
counter += 2;
|
|
}
|
|
totalCount += 1;
|
|
if (counter == SND_BUFFER_SIZE) {
|
|
fwrite(data,2,SND_BUFFER_SIZE,fd);
|
|
counter = 0;
|
|
}
|
|
}
|
|
|
|
void SndWvOut :: setMonoPan(MY_FLOAT aPan)
|
|
{
|
|
pan = aPan;
|
|
if (aPan < 0.0) {
|
|
pan = 0.0;
|
|
printf("Pan < 0.0, correcting to 0.0\n");
|
|
}
|
|
if (aPan > 1.0) {
|
|
pan = 1.0;
|
|
printf("Pan > 1.0, correcting to 1.0\n");
|
|
}
|
|
}
|