• Welcome to ASR. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

Sorana Flow — free macOS music player with DSP (feedback welcome)

Sorana Flow v1.8.2 — SIMD-Optimized DSP, Lock-Free RT Path, 61 Correctness Fixes


v1.8.2 is available. This release focuses on measurable audio engine improvements and correctness.


DSP Performance


All compute-heavy DSP has been moved to Apple's vDSP/Accelerate SIMD:


  • Convolution (partitioned overlap-add): vDSP_zvma complex multiply-accumulate → 3-5× throughput
  • HRTF binaural: vDSP_conv block-based FIR replaces per-sample scalar loop → 5-10× throughput
  • Minimum phase EQ: vDSP_biquad cascaded IIR → 2-3× throughput
  • Gain ramps: vDSP_vrampmul replaces per-sample multiply
  • Peak limiter: Padé [3,3] rational tanh approximation replaces std::tanh

DSP module compiles with -O3 -ffast-math -flto=thin.


RT Thread Safety


The real-time audio callback now has:


  • Zero blocking mutex locks (all converted to try_lock or lock-free atomics)
  • Zero heap allocations (all buffers pre-allocated in prepare())
  • Lock-free staged swap for convolution IR, HRTF filters, and EQ kernels
  • NaN/Inf sanitization in the peak limiter chain

Linear Phase EQ Transitions


Previous: single OLA instance → 29ms silence during kernel swap.Current: double-buffered OLA with:


  • FDL warmup counter (m_numKernelPartitions + 1 partitions before crossfade)
  • 128-sample equal-power crossfade (sqrt(t) / sqrt(1-t))
  • Batch kernel build (1 FFT per preset change, was 10)

The +1 warmup ensures the overlap-add buffer used for the first valid output was computed from a fully-populated frequency domain delay line — eliminating the residual pop from contaminated overlap data.


Correctness Audit


Full static analysis across 8 categories (thread safety, playback logic, DSP state, error handling, audio engine, UI, Apple Music integration, database). Results:


  • 5 critical fixes (use-after-free, data race, unguarded destruction)
  • 8 high fixes (gapless race conditions, shuffle/skip desync, device disconnect)
  • 27 medium fixes (atomic upgrades, channel guards, DSD validation, FTS5 injection)
  • 21 low fixes (defensive null checks, RAII, edge cases)

Key fix: shuffle/repeat skip used QTimer::singleShot(0) to defer track loading, creating a race window where the gapless pre-load would fire before the new track loaded. Solved with an atomic m_userSkipPending flag that suppresses stale gapless transitions during user-initiated skips.


New Features


  • AIFF/AIF playback
  • XSPF playlist import/export
  • ISO 226 equal loudness compensation (3 presets)

Download: https://soranaflow.com


Feedback welcome — especially from anyone running measurements or comparing against other players.
 
Thank you for this very impressive piece of work.

For proper application of HRTF/BRIR for stereo recordings you need so-called true stereo convolution. And since convolution filters depend on sampling rate, your software should choose the appropriate filters automatically or resample if required.

In case you plan to support HRTF/BRIR for multichannel recordings, you need to take the channel count and speaker layout into account, too.

In order to configure convolution you may want to have a look at the “Convolver standard“ as described here

With this, your software would support our (and other) personalized BRIR for speaker virtualization with headphones, and I would love to see that. On the other hand, I’m aware that this is a hell of work, hence just consider this well-meant ideas.
 
Thank you for this very impressive piece of work.

For proper application of HRTF/BRIR for stereo recordings you need so-called true stereo convolution. And since convolution filters depend on sampling rate, your software should choose the appropriate filters automatically or resample if required.

In case you plan to support HRTF/BRIR for multichannel recordings, you need to take the channel count and speaker layout into account, too.

In order to configure convolution you may want to have a look at the “Convolver standard“ as described here

With this, your software would support our (and other) personalized BRIR for speaker virtualization with headphones, and I would love to see that. On the other hand, I’m aware that this is a hell of work, hence just consider this well-meant ideas.
Thank you Philipp, and thanks for the detailed technical suggestions — coming from the founder of myHRTF, this means a lot.

You raise excellent points. Our current HRTF implementation uses basic convolution with bundled filters, so true stereo convolution (4-channel IR: LL, LR, RL, RR) and sample rate-aware filter selection are natural next steps. I wasn't aware of the Convolver standard — I'll definitely study it.

Supporting user-loadable BRIR files (including personalized ones from myHRTF) is something I'd love to implement. The convolution engine already handles partitioned overlap-add with vDSP, so extending it to true stereo with automatic resampling is architecturally feasible.

I'll look into the Convolver config format as a way to standardize how users load and configure their IR files. If you'd be open to it, I'd welcome any technical guidance on proper BRIR integration — getting the details right matters for something like spatial audio.

Appreciate the encouragement and the constructive feedback!
 
Apple Music integration exists but DSP cannot process streaming audio due to platform DRM restrictions — same as every other player.
I don't know how they do it, but Rogue Amoeba Audio Hijack can take sound from Apple Music, process it in all kinds of ways and send it to any possible output.
The lack of streaming makes any audio player 90% to 99% less interesting, imo. Far more important than binaural virtualization, if you ask me, and I am a sucker for binaural.
A bit more complicated, but via Blackhole I can do the same via Hang Loose Host or Kushview Element (which is not yet very robust).

Great Work!
 
v1.9.0 — Synology NAS Integration


Big update: Sorana Flow can now browse and play music directly from a Synology NAS.


What's new:


Synology NAS streaming



  • FileStation API browsing — navigate shared folders, sub-directories, and play audio files directly
  • Secure credential storage in macOS Keychain (Data Protection keychain, zero password prompts after first setup)
  • Auto-reconnect on app launch with saved credentials
  • Login retry dialog if authentication fails — no more restarting the app
  • Right-click to remove saved connections
  • DLNA/UPnP device discovery for non-Synology NAS devices

How it works technically:The app uses Synology's FileStation REST API (SYNO.FileStation.List) for folder browsing and constructs direct HTTP URLs for audio file streaming. Authentication goes through SYNO.API.Auth with session management. For DLNA devices, standard UPnP SSDP discovery + ContentDirectory browsing.


Audio files from NAS go through the same signal path as local files — full DSP pipeline (EQ, crossfeed, convolution, VST) is available. No transcoding on the NAS side.


Signal path for NAS playback:NAS (HTTP stream) → FFmpeg decoder → DSP pipeline → CoreAudio output


Same bit-perfect path as local files, just with network transport instead of disk I/O.


Other fixes in this release:


  • Fixed Qt signal connection issues that could cause disconnected state on launch
  • Fixed duplicate tree node creation for NAS devices
  • Cleaned up memory leaks in tree view data management

Free as always. macOS 14 Sonoma or later, Apple Silicon.


https://soranaflow.com


Feedback welcome — especially from anyone running Synology NAS setups who can test with different shared folder configurations and audio formats.
 
The new version has some nice features added but when I scan for and select a plugin I still get a crash - the app totally locks up and I need to force quit. It may be because I have a lot of multi ch plugins in my folders. Why no AU support?

I'm just troubleshooting here. I don't need or wouldn't use any of the DSP features of your app as those duties are done elsewhere (HLC) for multi ch needs.
Here's a system log dump if it can help.
 

Attachments

The new version has some nice features added but when I scan for and select a plugin I still get a crash - the app totally locks up and I need to force quit. It may be because I have a lot of multi ch plugins in my folders. Why no AU support?

I'm just troubleshooting here. I don't need or wouldn't use any of the DSP features of your app as those duties are done elsewhere (HLC) for multi ch needs.
Here's a system log dump if it can help.
Thanks for reporting this and for attaching the log.

I checked the log file but it only contains general macOS system messages (syslogd statistics and device events) — there's no SoranaFlow-specific crash data in it. To get the actual crash info, could you try one of these?

1. **Console.app** — Open Console.app, filter by "SoranaFlow", then reproduce the freeze. The relevant entries should appear in real time.
2. **Crash report** — After force-quitting, check ~/Library/Logs/DiagnosticReports/ for any file starting with "SoranaFlow". That would have the stack trace.
3. **Terminal** — Run the app from Terminal to see its own debug output:
`/Applications/SoranaFlow.app/Contents/MacOS/SoranaFlow`
Then trigger the plugin scan and paste whatever appears before it hangs.
4. You can submit through https://soranaflow.com/support

The freeze is very likely caused by multi-channel VST3 plugins. The scanner instantiates each plugin to read its metadata, and plugins expecting surround bus configurations can hang when the host only offers stereo. I'll add a scanner timeout so it skips unresponsive plugins instead of locking up.

Regarding AU support — it's on the roadmap but not implemented yet. It requires a different hosting framework (AudioToolbox) so it's a bigger feature to add properly.

If you don't need plugin features, you can avoid the issue entirely by not scanning for plugins.

Appreciate the testing — a crash report or Terminal output would help me fix this faster.
 
Last edited:
Here you go, dumped from Terminal. Yes, I could bypass scanning for plugins and be just fine with my usage but that wouldn't help you very much.
BTW, I could not locate any ~/Library/Logs/DiagnosticReports/ crash reports from an earlier session.
 

Attachments

Here you go, dumped from Terminal. Yes, I could bypass scanning for plugins and be just fine with my usage but that wouldn't help you very much.
BTW, I could not locate any ~/Library/Logs/DiagnosticReports/ crash reports from an earlier session.
Thanks for the Terminal output — much more useful than the system log.

I can see 24 VST3 plugins were scanned, but almost all of them failed to load:

- Voxengo AnSpec, SPAN, MarvelGEQ, TEQ-421, Bitter — these are Intel-only and won't load on Apple Silicon natively. If you have Rosetta versions installed, they won't work in Sorana Flow since it's a native ARM binary.
- MeldaProduction, SIR3, StandardCLIP, Dirac, HLConvolver, and others — "bundle couldn't be loaded" which usually means the plugin binary is incompatible or has missing dependencies.

The scan itself completed without hanging (took about 7 seconds for all 24), so the freeze you're experiencing likely happens when you try to select/load one of these failed plugins. I can see you double-clicked basiQ2 and got "Failed to create processor" — did the app freeze at that point, or was it a different plugin?

A few questions that would help me narrow it down:
1. Which specific plugin did you select when it froze?
2. Does it freeze during the scan phase (progress dialog), or when you click a plugin from the list to load it?
3. Do you have any AU-only plugins that don't have VST3 versions? That might be why you're asking about AU support.

For now, the plugins showing "wrong architecture" need Apple Silicon / Universal Binary updates from their developers. The ones showing "couldn't be loaded" may need reinstallation or updated versions.

I'll add better error handling so that selecting a failed plugin shows a clear error message instead of potentially hanging. Thanks for the detailed report — your setup with DAC8PRO and Dirac is exactly the kind of configuration I want to make sure works well.
 
1) Yes, it was basiQ2 that I selected and then everything froze. It's a simple VST with old fashioned B/M/T tone controls so I thought it had the most probability of success.
2) When I click a plugin
3) No, but AU is Apple's standard format and most people who use Macs prefer AU over VST3 if available.

- Voxengo AnSpec, SPAN, MarvelGEQ, TEQ-421, Bitter — these are Intel-only and won't load on Apple Silicon natively. If you have Rosetta versions installed, they won't work in Sorana Flow since it's a native ARM binary.

They actually do work but I don't use those plugins so moot point. I'm sorry to say all the other plugins are up to date and properly installed and available for any other Mac OS app I potentially use them with (HLC, SoundSource, JRiver). So, potentially, you still have some work to do. Integrating plugin support isn't easy, even Mitch struggled with it in the first few iterations of HLC and that's based on the JUCE code.

I don't use the DLBC plugin much, it does more measurable damage to a system than good but I understand why people like the convenience.

Don't get me wrong, I'm already liking your app, just trying to help.
 
1) Yes, it was basiQ2 that I selected and then everything froze. It's a simple VST with old fashioned B/M/T tone controls so I thought it had the most probability of success.
2) When I click a plugin
3) No, but AU is Apple's standard format and most people who use Macs prefer AU over VST3 if available.



They actually do work but I don't use those plugins so moot point. I'm sorry to say all the other plugins are up to date and properly installed and available for any other Mac OS app I potentially use them with (HLC, SoundSource, JRiver). So, potentially, you still have some work to do. Integrating plugin support isn't easy, even Mitch struggled with it in the first few iterations of HLC and that's based on the JUCE code.

I don't use the DLBC plugin much, it does more measurable damage to a system than good but I understand why people like the convenience.

Don't get me wrong, I'm already liking your app, just trying to help.
Thanks for the detailed follow-up, and for the kind words — feedback like this is exactly what I need.

You're right about the Voxengo plugins and others. I misspoke — the issue isn't that those plugins are Intel-only. They clearly work in HLC, SoundSource, and JRiver. The problem is on my end: my plugin loader is failing to load bundles that other hosts handle fine. That's a bug I need to fix, not a plugin compatibility issue. Thanks for the correction.

For basiQ2 specifically: the scan log shows "bundle couldn't be loaded," but when you double-click it, the app tries to load it again and hangs instead of showing an error. That's two bugs — the initial load failure, and the missing error handling on selection. I'll fix both.

On AU support — good timing. I'm actually implementing it right now. AU v3 via AUAudioUnit, scanning system Audio Units, same DSP pipeline integration as VST. Should be in the next release. You're right that most Mac users expect AU, and Apple's built-in effects (AUGraphicEQ, AUNBandEQ, etc.) would be immediately available.

I appreciate the context about HLC and JUCE — plugin hosting is genuinely one of the harder parts of audio software. Your setup with the DAC8 Pro and active crossovers is impressive, and exactly the kind of use case I want to support properly.

I'll post an update when the AU support and plugin loader fixes are ready.
 
Hi, great thing. It would be nice to have this on a github repo; many people could contribute, and port it to other platforms such as Linux, for RPi implementations.
Keep the good work up!
 
Hi, great thing. It would be nice to have this on a github repo; many people could contribute, and port it to other platforms such as Linux, for RPi implementations.
Keep the good work up!
Hi, I already have a github repo, but it's not open source and just freeware. And I prefer working alone making the app(Except UI/UX designer), And I am planning of porting to windows too. Thanks!
 
Last edited:
I'll post an update when the AU support and plugin loader fixes are ready.

I'll look forward to the update. I do a lot of beta testing for folks thus the overpopulated plugin folder, need to clean some of those out.
 
You said you're 19? I assume you want to learn, so why not open source it indeed? Let me guess: you're vibe-coding it. The more reason to go open source, because generated code needs expert coding experience to judge it properly. Just my 2 cents though...
 
You said you're 19? I assume you want to learn, so why not open source it indeed? Let me guess: you're vibe-coding it. The more reason to go open source, because generated code needs expert coding experience to judge it properly. Just my 2 cents though...
You're partly right — I do use AI assistance for UI design and the website since that's not my strength. The audio core (CoreAudio rendering, DSP chain, FFmpeg integration, VST3/AU plugin hosting) is hands-on work where I understand what every line does. Real-time audio has zero tolerance for code you don't fully understand.

On open source — I'm not against it in principle. Just not ready yet. I'd rather reach a point where the codebase is clean enough to be useful to others, rather than open something half-baked. For now, happy to answer any technical questions about the implementation.
 
Last edited:
I joined this site to find some simple data on my DAC and it's very nice to meet a Korean. It is also an honor to meet a young person who is a developer of a music driving program. My heart is beating very fast. I will replace the regret of how I wish I could do it by supporting Rookie 7423. 화이팅!
 
I joined this site to find some simple data on my DAC and it's very nice to meet a Korean. It is also an honor to meet a young person who is a developer of a music driving program. My heart is beating very fast. I will replace the regret of how I wish I could do it by supporting Rookie 7423. 화이팅!
Thank you very much! And I'm ruki(from haruki), not rookie haha
 
Last edited:
Back
Top Bottom