Fixed filter banks hang on mac os

Started by j_p_higgins, June 01, 2025, 02:17:42 AM

Previous topic - Next topic

j_p_higgins

There seems to be an intermittent fault where fixed filter banks (FILTER BANK) hang on mac just after printing "INFO: Running Filter" to the console.

Sometimes it will run fine but most of the time it hangs. I have recreated this bug in the command line so it seems it is an issue with the cdp process itself. I have tried troubleshooting in lldb but it is just giving me exit code -1 and nothing else useful. I have had reports of this happening on M macs and intel macs so it doesn't seem like it is arm mac specific.

On my most recent test it was hanging on most runs with most arguments but the last run it hung on I was calling:

filter bank 1 infile outfile 400 1.5 55 12000

The infile was a stereo wav.

There are some crash reports in this link: https://github.com/j-p-higgins/SoundThread/issues/75 although they seem to suggest the problem is with calling display_virtual_time however commenting out calls to that in the filter code and building the source didn't seem to make any difference

Is here the right place to report this or should I open an issue on github?

j_p_higgins

I've spent some time trying to troubleshoot this although my knowledge of C is pretty poor so I'm not doing the best job. I have no fixes yet but in case anyone looks into this, this is what I have found/tried:

  • From inserting some diagnostic prints in the code, it is getting as far as the main processing loop after the normalisation stage and "Info: Running Filter" however, it just loops for ever. On the first loop it reports to have processed some samples but the value of samps_left doesn't go down and after the first loop it just remains at this on every loop:

    samps_left: 1830700 | ssampsread: 0 | filter_tail: 0 | tail_extend: 0

    By the time it reaches the file writing stage in loop, sampsread is always 0.
  • This only seems to occur when it is called from the command line. Running this process within SoundLoom directly runs fine however, if I make it part of a batch file inside SoundLoom and run that from the batch window in SoundLoom it gets stuck looping. I did try forcing sloom to 1 in the code to see if that made a difference, it didn't make a difference but I'm not convinced I did it right.
  • It doesn't make any difference if the process runs with the -t or -s flags.
  • I tried forcing the normalisation scaling on the output to something very high in case the tail logic wasn't seeing a high enough level due to rounding but that didn't seem to make a difference.
  • Some users have reported that it runs fine first time after a reboot but not after that however, I haven't been able to replicate this personally.
  • Sometimes if the filter banks maximum frequency is set close to the minimum frequency it will run - mostly only with filter bank 6. I thought this might suggest denormals were the issue but flushing those didn't seem to make a difference.
  • It runs fine on windows, I haven't had a chance to test it on linux yet but I haven't had any reports from linux users of it not working

j_p_higgins

Some progress, the issue is being caused by the normalisation step although both that and the filtering seem to work fine individually. If I bypass normalisation by setting do_norm = 0 the process doesn't get stuck looping. I am not really sure though what is causing it to not get stuck. Some things to note:

  • sndseekEx is returning 0, although I haven't yet checked that it is actually succeeding at all steps
  • reset_filedata_counters doesn't reset ssampsread although manually resetting this to 0 didn't make any difference
  • I have now recreated the bug where it runs first time after a reboot but not any subsequent time, it will also sometimes run correctly if I duplicate the input file and run it again with the new file

I might have to stop trying to troubleshoot this now, I haven't done any programming in C since I was a teenager and this is getting a bit beyond me but hopefully these will be helpful pointers for someone who actually knows what they are doing!

j_p_higgins

I thought sndseekex might be the problem so added the function below and tried calling that instead. Doing this allows the process to run multiple times (at least on intel macs I don't have an arm mac for testing) although if I change any of the filter settings between runs the filter still loops around the processing section forever. I've tried adding some additional cleanup of dz at the end of main.c but it doesn't seem to be making any difference.

int safe_sndseek(dataptr dz) {
    // Get the input filename before closing
    const char* filename_tmp = snd_getfilename(dz->ifd[0]);
    if (!filename_tmp) {
        fprintf(stderr, "safe_sndseek: ERROR — could not retrieve filename from ifd[0] = %d\n", dz->ifd[0]);
        return -1;
    }

    // Allocate memory and copy the filename
    char* filename_buf = malloc(strlen(filename_tmp) + 1);
    if (!filename_buf) {
        fprintf(stderr, "safe_sndseek: ERROR — memory allocation failed for filename copy\n");
        return -1;
    }
    strcpy(filename_buf, filename_tmp);

    fprintf(stderr, "safe_sndseek: Retrieved filename = %s\n", filename_buf);

    // Close the input file
    fprintf(stderr, "safe_sndseek: Closing input file descriptor %d\n", dz->ifd[0]);
    sndcloseEx(dz->ifd[0]);

    // Reopen the input file
    dz->ifd[0] = sndopenEx(filename_buf, 0, 0);
    if (dz->ifd[0] < 0) {
        fprintf(stderr, "safe_sndseek: ERROR — failed to reopen input file: %s\n", filename_buf);
        free(filename_buf);
        return -2;
    }

    fprintf(stderr, "safe_sndseek: Reopened input file. New ifd[0] = %d\n", dz->ifd[0]);

    // Clean up
    free(filename_buf);

    // Reset internal counters for reading
    reset_filedata_counters(dz);
    fprintf(stderr, "safe_sndseek: reset_filedata_counters completed.\n");

    return 0;
}


j_p_higgins

Sorry to keep spamming the forum, I hope this info is useful to someone. I have a somewhat working solution.

Adding a lot of cleanup to free all the filter arrays in dz that I can find in the code after print_messages_and_close_sndfiles seems to make the process want to run multiple times with different filter modes and settings. What I have done is giving me a segfault error (exit code 11) when its done although it does run the filtering fine and produce the outfile. I think the segfault is probably just me trying to free something twice.

Seems like maybe mac is being picky about reallocating memory between runs and trying to reuse old things.

Not sure if this is the real fix, think I might just be sticking a plaster on the issue and hiding it. But, hopefully knowing that changing this and replacing soundseekx make this process want to run properly on mac will point someone who actually knows what they're doing in the right direction of the fault.

My guess is that as SoundLoom calls each process and closes it up fully after run, that that is why it works when called directly in SoundLoom but that calling it multiple times in the same terminal session or batch file doesn't close it fully and that is why some stuff is getting left over and is causing issues on subsequent runs.