const char * UsageLines [] = {
"Usage: swmix ((input file) (input weight) )+",
"Mixes specified sound files, writes result sound file to",
"standard output.",
"All sound files are headerless signed word (.sw): two bytes",
"per sample, least significant byte first.",
"(input weight) must be an integer > 0",
"May 16, 2011. Newest is at gopher -p users/julianbr sdf.org",
};
const int NumUsageLines = sizeof (UsageLines)/sizeof (UsageLines [0] );
#include <stdlib.h>
#include <stdio.h>
void Mix (FILE * * InputHdls, int * Weights, int NumInputs)
{
unsigned long int UnsignedValue;
int TotalWeight;
long int WeightedValue;
int InputNum, EndOfAllInputs, ms, ls;
TotalWeight = 0;
for (InputNum = 0; InputNum < NumInputs; InputNum++)
TotalWeight += Weights [InputNum];
EndOfAllInputs = 0;
while (!EndOfAllInputs) {
EndOfAllInputs = 1;
WeightedValue = 0;
for (InputNum = 0; InputNum < NumInputs; InputNum++) {
if (Weights [InputNum] > 0) {
ls = fgetc (InputHdls [InputNum] );
if (ls == EOF)
Weights [InputNum] = 0;
else {
ms = fgetc (InputHdls [InputNum] );
if (ms == EOF)
Weights [InputNum] = 0;
}
}
if (Weights [InputNum] > 0) {
UnsignedValue = 256*(ms ^ 128) + ls;
WeightedValue += Weights [InputNum]
*(UnsignedValue - 32768);
EndOfAllInputs = 0;
}
}
if (!EndOfAllInputs) {
UnsignedValue = 32768 + (WeightedValue/TotalWeight);
putchar (UnsignedValue%256);
putchar ((UnsignedValue/256) ^ 128);
}
}
}
int main (int argc, char * argv [] )
{
FILE * * InputHdls;
int i, ok, NumInputs, InputNum, * Weights;
char c;
if (argc < 2) {
for (i = 0; i < NumUsageLines; i++)
printf ("%s\n", UsageLines [i] );
}
else {
ok = 1;
NumInputs = (argc - 1)/2;
if (NumInputs > 0) {
InputHdls = malloc (
NumInputs*sizeof (InputHdls [0] ) );
if (InputHdls == NULL) {
fprintf (stderr, "***swmix: Not enough");
fprintf (stderr, " memory.\n");
ok = 0;
}
Weights = malloc (
NumInputs*sizeof (Weights [0] ) );
if (Weights == NULL) {
fprintf (stderr, "***swmix: Not enough");
fprintf (stderr, " memory.\n");
ok = 0;
}
}
for (InputNum = 0; InputNum < NumInputs; InputNum++) {
InputHdls [InputNum] = fopen (argv [2*InputNum + 1],
"rb");
if (InputHdls [InputNum] == NULL) {
fprintf (stderr, "***swmix: \"");
fprintf (stderr, "%s", argv [2*InputNum + 1] );
fprintf (stderr, "\" not found.\n");
ok = 0;
}
if (sscanf (argv [2*InputNum + 2],
"%d%c", Weights + InputNum, & c) != 1
|| Weights [InputNum] < 1) {
fprintf (stderr, "***swmix:");
fprintf (stderr, " Expecting number > 0");
fprintf (stderr, " for weight, found \"");
fprintf (stderr, "%s", argv [2*InputNum + 2] );
fprintf (stderr, "\".\n");
ok = 0;
}
}
if (argc > 2*NumInputs + 1) {
fprintf (stderr, "***swmix: Improper");
fprintf (stderr, " \"%s\"", argv [2*NumInputs + 1] );
fprintf (stderr, ".\n");
ok = 0;
}
if (ok)
Mix (InputHdls, Weights, NumInputs);
for (InputNum = 0; InputNum < NumInputs; InputNum++) {
if (InputHdls [InputNum] != NULL)
fclose (InputHdls [InputNum] );
}
if (NumInputs > 0) {
if (InputHdls != NULL)
free (InputHdls);
if (Weights != NULL)
free (Weights);
}
}
return 0;
}