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; }