Skip to content

[BUG] Malloc error on macOS when initializing the MiniAudioEngine with sample rate of 16000 #67

Description

@earlwilson

Operating System & Version

MacOS 13.7.4

Architecture

ARM64 (M1)

.NET Runtime & Version

.NET 9

Audio Backend Used (if known)

MiniAudioEngine

Specific Hardware (if relevant)

M1 Macbook Air. Default built in speakers and microphone.

2. Description of the Issue

When I initialize an instance of MiniAudioEngine with the following settings

Engine = new MiniAudioEngine(
    sampleRate: 16000, 
    capability: Capability.Mixed,
    sampleFormat: SampleFormat.F32,
    channels: 1 
);

I get an intermittent error in the output which occurs right as the MiniAudioEngine is initialized.

(62520,0x16e453000) malloc: Incorrect checksum for freed object 0x104019a00: probably modified after being freed.
Corrupt value: 0xb726a590b71f9512
(62520,0x16e453000) malloc: *** set a breakpoint in malloc_error_break to debug

Interestingly it does not crash If i change the sample rate to either 8000, 22050, 44100, 48000 or if I set the capability to Capability.Record

3. Does it work correctly on other platforms?

Yes

Which platforms work correctly? (If "Yes" above)

It works with out error on my Raspberry Pi 5 running Debian 6.6.

4. Steps to Reproduce (on the affected platform)

  1. Initialize an instance of MiniAudioEngine on a Mac with the settings I listed.
  2. Run the application
  3. You will see that there are malloc errors.

5. Expected Behavior (on the affected platform)

It is expected that the application can setup the MiniAudioEngine without crashing

6. Current Behavior (on the affected platform)

It currently crashes immediately when initializing the MiniAudioEngine.

7. Minimal Reproducible Example (MRE)

public void Initialize()
        {
            Engine = new MiniAudioEngine(
                sampleRate: 16000, 
                capability: Capability.Mixed,
                sampleFormat: SampleFormat.F32,
                channels: 1 
            );
            // Error happens above ^

            StartCapture();
        }

8. Error Messages and Stack Trace (if applicable, from the affected platform)

(69172,0x1ea4ce140) malloc: Incorrect checksum for freed object 0x12482ae00: probably modified after being freed.
Corrupt value: 0x388f638438ac7370
(69172,0x1ea4ce140) malloc: *** set a breakpoint in malloc_error_break to debug

9. SoundFlow Version

1.1.1

10. Additional Context

I can get it to run properly maybe 1 out of every 10 attempts. I have attempted this with a variety of Dispose / Clean up strategies to see if it was related to that.

Lastly, I gave my best effort at debugging the issue, I see the crash happens in the InitializeDeviceInternal function at the result = Native.DeviceStart(_device); line in MiniAudioEngine.cs

Requirements Checklist

  • I have searched the existing issues to ensure this platform-specific issue has not already been reported.
  • I have clearly specified the affected platform(s) and environment details.
  • I have provided detailed steps to reproduce the issue on the affected platform.
  • I have indicated if the issue is confirmed to work correctly on other platforms.

Activity

  1. moved this to Bugs in SoundFlowon Jul 9, 2025
  2. LSXPrime commented on Jul 9, 2025

    @LSXPrime
    Owner

    I will investigate this. Since Native.DeviceStart(_device); calls ma_device_start (from the miniaudio library) and transfers control outside SoundFlow at that point, it's possible the issue lies with miniaudio on macOS. However, I still suspect a problem with the device enumeration logic. If it was the SoundFlow native wrapper fault, I will include a potential fix in the next release.

  3. LSXPrime commented on Jul 12, 2025

    @LSXPrime
    Owner

    Can you confirm it's the same as miniaudio duplex example?

  4. earlwilson commented on Jul 12, 2025

    @earlwilson
    Author

    Can you confirm it's the same as miniaudio duplex example?

    How exactly do I do that? Or can you explain more? What am i confirming is the same as the duplex example?

  5. LSXPrime commented on Jul 12, 2025

    @LSXPrime
    Owner

    Just compile this example and check if duplex mode is getting initialized and working correctly

    Here's exactly what I need you to do:

    1. Locate the file: Go into the examples/duplex_effect.c file.
    2. Find the line: Look for line L57, which is:
      deviceConfig = ma_device_config_init(ma_device_type_duplex);
    3. Add this exact line right after it:
      deviceConfig.sampleRate = 16000;
      (So, it should look like this in your code:)
      deviceConfig = ma_device_config_init(ma_device_type_duplex);
      deviceConfig.sampleRate = 16000;
    4. Compile the example with something like GCC.

    And Report back if duplex initialize correctly or you still experience the same behavior or there any new error messages in the console?

    I want to make sure if it's an issue with the duplex mode in the native library itself, or we are initializing it incorrectly.

    After some digging, I found that on line 34307 in miniaudio.h, it shows that Mixed (Duplex) Mode isn't supported on CoreAudio (macOS backend).

    static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_device_init_internal_data__coreaudio* pData, void* pDevice_DoNotReference)   /* <-- pDevice is typed as void* intentionally so as to avoid accidentally referencing it. */
    {
        ma_result result = MA_SUCCESS;
        OSStatus status;
        UInt32 enableIOFlag;
        AudioStreamBasicDescription bestFormat;
        ma_uint32 actualPeriodSizeInFrames;
        AURenderCallbackStruct callbackInfo;
    #if defined(MA_APPLE_DESKTOP)
        AudioObjectID deviceObjectID;
    #endif
    
        /* This API should only be used for a single device type: playback or capture. No full-duplex mode. */
        if (deviceType == ma_device_type_duplex) {
            return MA_INVALID_ARGS;
        }
    
    
    
    
    // It's called in the main macOS (Core Audio) Initializing function below at line 34882
    
    static ma_result ma_device_init__coreaudio(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture)
    {
        ma_result result;
    
        MA_ASSERT(pDevice != NULL);
        MA_ASSERT(pConfig != NULL);
    
        if (pConfig->deviceType == ma_device_type_loopback) {
            return MA_DEVICE_TYPE_NOT_SUPPORTED;
        }
    
        /* No exclusive mode with the Core Audio backend for now. */
        if (((pConfig->deviceType == ma_device_type_capture  || pConfig->deviceType == ma_device_type_duplex) && pDescriptorCapture->shareMode  == ma_share_mode_exclusive) ||
            ((pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) && pDescriptorPlayback->shareMode == ma_share_mode_exclusive)) {
            return MA_SHARE_MODE_NOT_SUPPORTED;
        }
    
        /* Capture needs to be initialized first. */
        if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
            ma_device_init_internal_data__coreaudio data;
            data.allowNominalSampleRateChange = pConfig->coreaudio.allowNominalSampleRateChange;
            data.formatIn                     = pDescriptorCapture->format;
            data.channelsIn                   = pDescriptorCapture->channels;
            data.sampleRateIn                 = pDescriptorCapture->sampleRate;
            MA_COPY_MEMORY(data.channelMapIn, pDescriptorCapture->channelMap, sizeof(pDescriptorCapture->channelMap));
            data.periodSizeInFramesIn         = pDescriptorCapture->periodSizeInFrames;
            data.periodSizeInMillisecondsIn   = pDescriptorCapture->periodSizeInMilliseconds;
            data.periodsIn                    = pDescriptorCapture->periodCount;
            data.shareMode                    = pDescriptorCapture->shareMode;
            data.performanceProfile           = pConfig->performanceProfile;
            data.registerStopEvent            = MA_TRUE;
    
            /* Need at least 3 periods for duplex. */
            if (data.periodsIn < 3 && pConfig->deviceType == ma_device_type_duplex) {
                data.periodsIn = 3;
            }
    
            result = ma_device_init_internal__coreaudio(pDevice->pContext, ma_device_type_capture, pDescriptorCapture->pDeviceID, &data, (void*)pDevice);
            if (result != MA_SUCCESS) {
                return result;
            }
    

    I'm not entirely sure why it's returning MA_INVALID_ARGS instead of MA_DEVICE_TYPE_NOT_SUPPORTED, or why you're having an allocation issue on your side, or why it's even working with any samplerate that's not 16KHz. Someone else also reported it working on their Mac without crashes but without audio.

    Actually, never mind – I'll just remove miniaudio's default Mixed mode device type. The next version release will have a more fine-grained approach by initializing playback and recording devices together at the same time at the soundflow level, which should work on any platform that supports both playback and recording.

  6. added
    in-progressThis issue is actively being worked on; development is currently in progress.
    on Jul 12, 2025
  7. moved this from Bugs to In progress in SoundFlowon Jul 12, 2025
  8. earlwilson commented on Jul 17, 2025

    @earlwilson
    Author

    Sorry, just got the opportunity to do this.

    When I compile and run duplex_effect.c I can successfully talk and hear my self in real time with a roboty vocoder effect applied to it.

  9. earlwilson commented on Jul 17, 2025

    @earlwilson
    Author

    @LSXPrime When is the next version planned for release?

  10. LSXPrime commented on Jul 21, 2025

    @LSXPrime
    Owner

    V1.1.2 and V1.2.0 are now available. Check the RELEASE NOTES for changes and consult the DOCUMENTATION before updating to V1.2.0.

    Please update to V1.2.0 and merge the changes. For Mixed Mode, visit the duplex device section here.
    I am closing this for now. If the issue still persists with the new architecture, please reopen this issue.

  11. moved this from In progress to Done in SoundFlowon Jul 21, 2025
  12. closed this as completedby moving to Done in SoundFlowon Jul 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingin-progressThis issue is actively being worked on; development is currently in progress.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions