Here is a simple sine wave generator in awk.
It produces 1 second of a 1000 Hz sine wave
scaled to an amplitude of 24 bits, at 44100Hz.
The individual 24bit samples are printed out
as three bytes, from lowest to highest.

$ cat sin.awk
BEGIN {
        tone = 1000;
        duration = 1;
        amplitude = 1;
        samplerate = 44100;
        numsamples = duration * samplerate;
        bitspersample = 24;
        pi = 4 * atan2(1,1);

        for (b = 0 ; b < bitspersample ; b++)
                amplitude *= 2;
        amplitude -= 1;

        for (s = 0; s < numsamples; s++) {
                sample = sin(2 * pi * tone * s / samplerate);
                sample = int(amplitude * sample);
                #printf("%d\n", sample);
                for (b = 0; b < bitspersample/8; b++) {
                        printf("%c", sample % 256); # zero?
                        sample /= 256;
                }
        }
}

The result is different with system awk (version 20110810)
and mawk-1.3.4.20140914; this is on current/amd64.

If I print out just the samples (24bit integers, as %d),
the results are indentical. If I print out the individual
bytes of those 24 bit samples (the innermost for loop),
the results differ; the difference is that that the system awk
does NOT print out some of the zeros.

$ awk -f sin.awk | hexdump -C | head > awk
$ mawk -f sin.awk | hexdump -C | head > mawk
$ diff awk mawk | head
7,10c7,10
< 00000060  31 03 bf 04 01 52 39 03  77 92 0a 0f ea 16 14 27  |1....R9.w......'|
< 00000070  e2 7b 3d 04 ee 56 77 d2  73 59 93 93 ee 8b b5 f8  |.{=..Vw.sY......|
< 00000080  0b d9 4e 5b fd 8e bc 20  fa 74 44 42 ca 66 46 0a  |..N[... .tDB.fF.|
< 00000090  87 b9 8d a4 7e bb be c6  0b d5 cc 0a e7 36 5b f4  |....~........6[.|
---
> 00000060  31 00 03 bf 04 01 52 39  03 77 92 0a 0f ea 16 14  |1.....R9.w......|
> 00000070  00 27 e2 7b 3d 04 ee 56  77 d2 73 59 93 93 ee 8b  |.'.{=..Vw.sY....|
> 00000080  b5 f8 0b d9 4e 5b fd 8e  bc 20 fa 74 44 42 ca 66  |....N[... .tDB.f|
> 00000090  46 0a 87 b9 8d a4 7e bb  be c6 0b d5 cc 0a e7 36  |F.....~........6|

mawk's printf("%c", ...) of a zero byte always prints a zero byte (^@)
while system awk's printf("%c", ...) of a zero bytes sometimes prints
a zero byte, and sometimes prints nothing.

awk variables are not typed; can it be that the zero byte
is sometimes considered a delimiter of an empty string?
Is there a better way in awk to print a 'raw' byte than printf("%c")?

        Jan

Reply via email to