Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@olilarkin
Copy link
Member

  • Vendor RtAudio 6.0.1 (from 5.1.0)
  • Vendor RtMidi 6.0.0
  • Add Steinberg ASIO SDK 2.3 from https://github.com/audiosdk/asio
  • Update IPlugAPP to support RtAudio 6.x API changes:
    • Use getDeviceIds() instead of getDeviceCount() + index
    • Replace RtAudioError exceptions with RtAudioErrorType return values
    • Use std::map for device ID to name mapping
    • Remove probed field checks (devices from getDeviceIds() are already probed)
  • Removed unnecessary docs, tests, and autotools files from vendored deps
  • Kept CMake build scripts for both libraries

- Vendor RtAudio 6.0.1 (from 5.1.0)
- Vendor RtMidi 6.0.0
- Add Steinberg ASIO SDK 2.3 from https://github.com/audiosdk/asio
- Update IPlugAPP to support RtAudio 6.x API changes:
  - Use getDeviceIds() instead of getDeviceCount() + index
  - Replace RtAudioError exceptions with RtAudioErrorType return values
  - Use std::map for device ID to name mapping
  - Remove probed field checks (devices from getDeviceIds() are already probed)
- Removed unnecessary docs, tests, and autotools files from vendored deps
- Kept CMake build scripts for both libraries
@claude
Copy link

claude bot commented Dec 9, 2025

PR Review: Update RtAudio and RtMidi to latest version

Overview

This PR updates RtAudio from 5.1.0 to 6.0.1 and RtMidi to 6.0.0, along with adding the ASIO SDK 2.3. The core implementation changes in IPlugAPP correctly adapt to the new RtAudio 6.x API.


✅ Positive Findings

Code Quality

  • Clean API migration: The implementation correctly adopts all RtAudio 6.x API changes:
    • ✓ Uses getDeviceIds() instead of index-based iteration (IPlugAPP_host.cpp:269)
    • ✓ Properly handles RtAudioErrorType return values instead of exceptions (lines 563, 607, 625)
    • ✓ Implements std::map<uint32_t, std::string> for device ID→name mapping (line 252)
    • ✓ Removes obsolete probed field checks

Best Practices

  • Error handling: Return value checking is consistent throughout (lines 563-567, 609-613, 627-631)
  • Resource management: Proper use of std::unique_ptr for RAII (lines 221-223)
  • Style compliance: Changes follow iPlug2 coding conventions (2-space indentation, member variable naming)

⚠️ Issues & Concerns

1. Critical: Empty Error Callback Implementation

Location: IPlugAPP_host.cpp:784-787

void IPlugAPPHost::ErrorCallback(RtAudioErrorType type, const std::string &errorText)
{
  //TODO:
}

Issue: The ErrorCallback is registered but completely unimplemented. Audio errors will be silently ignored.

Impact: High - Users won't be notified of audio subsystem failures (device disconnections, driver errors, etc.)

Recommendation: Add logging at minimum:

void IPlugAPPHost::ErrorCallback(RtAudioErrorType type, const std::string &errorText)
{
  DBGMSG("RtAudio Error [%d]: %s\n", type, errorText.c_str());
  // Consider: MessageBox for critical errors if not mExiting
}

2. Bug: Copy Constructor Error

Location: IPlugAPP_host.h:135-136

, mAudioOutChanL(obj.mAudioInChanL)  // ← Wrong! Should be mAudioOutChanL
, mAudioOutChanR(obj.mAudioInChanR)  // ← Wrong! Should be mAudioOutChanR

Issue: Copy constructor copies input channels to output channels (pre-existing bug, not introduced by this PR)

Impact: Medium - Audio routing will be incorrect when AppState is copied

Recommendation: Fix the typos (though this is unrelated to the RtAudio update)

3. Potential Issue: Error Callback Never Registered

Location: IPlugAPP_host.cpp:607

RtAudioErrorType err = mDAC->openStream(&oParams, iParams.nChannels > 0 ? &iParams : nullptr, 
                                         RTAUDIO_FLOAT64, sr, &mBufferSize, &AudioCallback, 
                                         this, &options);

Issue: The ErrorCallback static method exists but is never registered with RtAudio. RtAudio 6.x requires setting the error callback separately.

Impact: Medium - Error callback won't be invoked even if implemented

Recommendation: After creating mDAC, register the error callback:

mDAC->setErrorCallback(&ErrorCallback);

4. Namespace Inconsistency

Issue: RtAudio 6.x uses rt::audio namespace (RtAudio.h:88-89), but the code doesn't qualify types or use using declarations

Status: This may work if RtAudio provides backwards compatibility typedefs in the global namespace. Verify that compilation succeeds on all platforms (Windows ASIO/DS, macOS CoreAudio).


🔒 Security Considerations

Buffer Safety ✓

  • SysEx size validation is present (IPlugAPP_host.cpp:761-764)
  • No obvious buffer overflows in the changes

Input Validation ✓

  • Device ID lookups handle -1 returns appropriately (lines 415-442)
  • Null pointer checks for MIDI devices (line 307)

⚡ Performance Considerations

Real-time Safety ✓

  • Audio callback remains allocation-free (IPlugAPP_host.cpp:688-749)
  • No STL containers resized in callback
  • No mutex locking in audio thread (correct for this design)

Memory Management ✓

  • Dependency update doesn't change memory usage patterns
  • std::map for device mapping is appropriate (only accessed during device enumeration)

🧪 Test Coverage

Missing Tests

This is a major dependency update crossing API versions. Consider:

  1. Manual testing checklist:

    • Device enumeration on Windows DS
    • Device enumeration on Windows ASIO
    • Device enumeration on macOS CoreAudio
    • Device hot-plug/unplug scenarios
    • MIDI I/O with various devices
    • Buffer size changes
    • Sample rate changes
    • Multi-channel configurations
  2. Error scenarios:

    • Invalid device IDs
    • Device disconnection during playback
    • Driver errors

📝 Recommendations

Priority 1 (Should fix before merge)

  1. Implement error callback - Critical for production use
  2. Register error callback with RtAudio - Otherwise it will never fire
  3. Verify namespace compatibility - Ensure it compiles on all target platforms

Priority 2 (Can address later)

  1. Fix AppState copy constructor bug (pre-existing)
  2. Add error recovery logic for device disconnection
  3. Consider deprecation warnings for removed APIs

Priority 3 (Nice to have)

  1. Add automated tests for device enumeration
  2. Document breaking changes in CHANGELOG
  3. Add migration guide for downstream users

📦 Dependency Management ✓

  • Vendoring strategy is sound (removed unnecessary test/doc files)
  • CMake build scripts retained (good for future maintenance)
  • License files included (ASIO SDK, RtAudio)

Summary

Overall Assessment: Good technical execution of the API migration. The core implementation is solid, but the empty error callback is a blocker that should be addressed before merging. The code follows iPlug2 conventions and handles the RtAudio 6.x API changes correctly.

Recommendation: Approve with changes - Fix error callback implementation, then merge.


Review generated per CLAUDE.md guidelines - focused on realtime safety, cross-platform compatibility, and audio-specific concerns.

Implement ErrorCallback with DBGMSG logging instead of empty TODO
Fix AppState copy constructor: use mAudioOutChanL/R instead of mAudioInChanL/R

This was a pre-existing bug where output channel assignments incorrectly
copied from input channel values.
Register ErrorCallback with RtAudio after DAC creation

RtAudio 6.x requires the error callback to be set separately via
setErrorCallback() rather than passed to the constructor.
@claude
Copy link

claude bot commented Dec 9, 2025

Pull Request Review: Update RtAudio and RtMidi to Latest Version

Overview

This PR updates RtAudio from 5.1.0 to 6.0.1 and RtMidi to 6.0.0, adds the ASIO SDK 2.3, and updates IPlugAPP to work with the RtAudio 6.x API changes. The changes are substantial (337 files, +12K/-111K lines) but largely consist of vendored library updates.

Code Quality & Best Practices

✅ Strengths

  1. Proper API Migration: The IPlugAPP code correctly adapts to RtAudio 6.x API changes:

    • getDeviceIds() replaces device enumeration by index (IPlugAPP_host.cpp:269)
    • Error handling changed from exceptions to return values (IPlugAPP_host.cpp:566, 610, 628)
    • Uses std::map<uint32_t, std::string> for device ID-to-name mapping (IPlugAPP_host.h:252)
  2. Consistent Error Handling: Proper checking of RtAudioErrorType return values with appropriate logging:

    RtAudioErrorType err = mDAC->openStream(...);
    if (err != RTAUDIO_NO_ERROR) {
      std::cerr << mDAC->getErrorText() << std::endl;
      return false;
    }
  3. Backwards Compatibility: Removed deprecated/unnecessary code (probed field checks) as devices from getDeviceIds() are pre-validated.

⚠️ Potential Issues

  1. Memory Safety in Error Path (IPlugAPP_host.cpp:566-570):

    RtAudioErrorType err = mDAC->abortStream();
    if (err != RTAUDIO_NO_ERROR) {
      std::cerr << mDAC->getErrorText() << std::endl;
    }

    If mDAC is in an invalid state, calling getErrorText() could be unsafe. Consider checking mDAC validity first.

  2. Race Condition in CloseAudio (IPlugAPP_host.cpp:561-564):

    mAudioEnding = true;
    while (!mAudioDone)
      Sleep(10);

    The busy-wait loop could theoretically hang if the audio callback doesn't set mAudioDone. Consider adding a timeout or using condition variables.

  3. String Comparison in Device Lookup (IPlugAPP_host.cpp:213-214):

    if (!strcmp(deviceNameToTest, pair.second.c_str()))
      return pair.first;

    This is correct but could fail if device names have leading/trailing whitespace. Consider trimming names during insertion in mAudioIDDevNames.

  4. Platform-Specific String Handling (IPlugAPP_host.cpp:276-281):
    The macOS device name truncation (removing prefix before ": ") is hard-coded. This could break if Apple changes device naming conventions. Consider making this more robust or configurable.

Performance Considerations

✅ Good Practices

  1. Efficient Device Enumeration: Using getDeviceIds() is more efficient than the old index-based approach, as it returns only valid devices.

  2. Map-Based Lookup: Using std::map for device ID lookups (IPlugAPP_host.h:252) is appropriate for this use case.

💡 Suggestions

  1. Reserve Vector Capacity (IPlugAPP_host.cpp:265-267):

    mAudioInputDevs.clear();
    mAudioOutputDevs.clear();
    mAudioIDDevNames.clear();

    Consider calling reserve() on vectors if you know approximate device counts to avoid reallocations.

  2. Avoid String Copies (IPlugAPP_host.cpp:274):

    std::string deviceName = info.name;

    Could use const std::string& to avoid unnecessary copy before the substr operation.

Security Concerns

⚠️ Minor Issues

  1. Buffer Overflow Risk (IPlugAPP_host.cpp:766-767):

    if(pMsg->size() > MAX_SYSEX_SIZE) {
      DBGMSG("SysEx message exceeds MAX_SYSEX_SIZE\n");
      return;
    }

    Good check! However, ensure MAX_SYSEX_SIZE is defined appropriately. The SysExData structure should validate buffer bounds.

  2. MIDI Message Validation (IPlugAPP_host.cpp:777-783):
    MIDI messages are constructed from callback data without thorough validation. While RtMidi typically provides valid data, adding basic MIDI message validation would be more defensive.

Test Coverage

⚠️ Concerns

  1. No Visible Tests: The PR doesn't include tests for the RtAudio 6.x integration. Consider:

    • Unit tests for device enumeration edge cases (no devices, device disconnect)
    • Integration tests for audio stream lifecycle
    • Tests for error handling paths
  2. Example Projects: Did you verify that all example projects still build and run with the new APIs? The standalone app examples would be particularly important to test.

Additional Recommendations

  1. Documentation: Update any documentation that references RtAudio 5.x API usage patterns.

  2. Migration Guide: Consider adding migration notes for users who might be using RtAudio directly in their plugins.

  3. Version Macros: The new RtAudio 6.0.1 defines version macros (RtAudio.h:49-52). Consider using these for compile-time compatibility checks if needed.

  4. ASIO SDK License: Good addition of LICENSE.txt files for ASIO SDK. Ensure these are properly acknowledged in project documentation.

  5. Cleanup Verification: Confirm that removal of autotools files, tests, and docs from vendored dependencies doesn't break any build configurations (especially CI).

Summary

This is a well-executed dependency upgrade with proper API migration. The core changes to IPlugAPP correctly handle the RtAudio 6.x API differences. Main concerns are around error handling robustness and the lack of visible tests. The code follows iPlug2 conventions (2-space indentation, member variable naming with 'm' prefix).

Recommendation: ✅ Approve with Minor Concerns

The PR is fundamentally sound, but consider:

  • Adding timeout to the busy-wait loop in CloseAudio()
  • Adding tests for the new RtAudio integration
  • Verifying all example projects build and run correctly
  • Documenting the API migration for end users

Great work on maintaining backwards compatibility while upgrading to the latest audio I/O libraries!

@olilarkin olilarkin marked this pull request as draft December 9, 2025 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants