Task: Audio overlap loop

C: #include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include "wren.h"

void C_getInput(WrenVM* vm) {
    int maxSize = (int)wrenGetSlotDouble(vm, 1) + 2;
    char input[maxSize];
    fgets(input, maxSize, stdin);
    __fpurge(stdin);
    input[strcspn(input, "\n")] = 0;
    wrenSetSlotString(vm, 0, (const char*)input);
}

void C_play(WrenVM* vm) {
    const char *args = wrenGetSlotString(vm, 1);
    char command[strlen(args) + 5];
    strcpy(command, "play ");
    strcat(command, args);
    system(command);
}

WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature) {
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "C") == 0) {
            if (isStatic && strcmp(signature, "getInput(_)") == 0) return C_getInput;
            if (isStatic && strcmp(signature, "play(_)") == 0) return C_play;
        }
    }
    return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
    switch (errorType) {
        case WREN_ERROR_COMPILE:
            printf("[%s line %d] [Error] %s\n", module, line, msg);
            break;
        case WREN_ERROR_STACK_TRACE:
            printf("[%s line %d] in %s\n", module, line, msg);
            break;
        case WREN_ERROR_RUNTIME:
            printf("[Runtime Error] %s\n", msg);
            break;
    }
}

char *readFile(const char *fileName) {
    FILE *f = fopen(fileName, "r");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    rewind(f);
    char *script = malloc(fsize + 1);
    fread(script, 1, fsize, f);
    fclose(f);
    script[fsize] = 0;
    return script;
}

int main(int argc, char **argv) {
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.bindForeignMethodFn = &bindForeignMethod;
    WrenVM* vm = wrenNewVM(&config);
    const char* module = "main";
    const char* fileName = "audio_overlap_loop.wren";
    char *script = readFile(fileName);
    WrenInterpretResult result = wrenInterpret(vm, module, script);
    switch (result) {
        case WREN_RESULT_COMPILE_ERROR:
            printf("Compile Error!\n");
            break;
        case WREN_RESULT_RUNTIME_ERROR:
            printf("Runtime Error!\n");
            break;
        case WREN_RESULT_SUCCESS:
            break;
    }
    wrenFreeVM(vm);
    free(script);
    return 0;
}




Go: package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "os/exec"
    "strconv"
)

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func main() {
    fileName := "loop.wav"
    scanner := bufio.NewScanner(os.Stdin)
    reps := 0
    for reps < 1 || reps > 6 {
        fmt.Print("Enter number of repetitions (1 to 6) : ")
        scanner.Scan()
        input := scanner.Text()
        check(scanner.Err())
        reps, _ = strconv.Atoi(input)
    }

    delay := 0
    for delay < 50 || delay > 500 {
        fmt.Print("Enter delay between repetitions in microseconds (50 to 500) : ")
        scanner.Scan()
        input := scanner.Text()
        check(scanner.Err())
        delay, _ = strconv.Atoi(input)
    }

    decay := 0.0
    for decay < 0.2 || decay > 0.9 {
        fmt.Print("Enter decay between repetitions (0.2 to 0.9) : ")
        scanner.Scan()
        input := scanner.Text()
        check(scanner.Err())
        decay, _ = strconv.ParseFloat(input, 64)
    }

    args := []string{fileName, "echo", "0.8", "0.7"}
    decay2 := 1.0    
    for i := 1; i <= reps; i++ {
        delayStr := strconv.Itoa(i * delay)
        decay2 *= decay
        decayStr := strconv.FormatFloat(decay2, 'f', -1, 64)        
        args = append(args, delayStr, decayStr)        
    }
    cmd := exec.Command("play", args...)    
    err := cmd.Run()
    check(err)
}