Repository navigation
feat(player): add reverse playback and fix device/decoder issues #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,11 +16,11 @@ jobs: | |
| matrix: | ||
| include: | ||
| - arch: x64 | ||
| os: windows-latest | ||
| os: windows-2025 | ||
| msystem: MINGW64 | ||
| mingw-package-prefix: mingw-w64-x86_64 | ||
| - arch: x86 | ||
| os: windows-latest | ||
| os: windows-2025 | ||
| msystem: MINGW32 | ||
| mingw-package-prefix: mingw-w64-i686 | ||
| - arch: arm64 | ||
|
|
@@ -368,6 +368,29 @@ jobs: | |
| -DCMAKE_OSX_ARCHITECTURES=arm64 \ | ||
| -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 | ||
| cmake --build . --parallel --verbose | ||
|
|
||
| - name: Patch Info.plist for App Store Validation | ||
| run: | | ||
| PLIST="build/runtimes/ios-arm64/native/soundflow-ffmpeg.framework/Info.plist" | ||
| if [ -f "$PLIST" ]; then | ||
| echo "Patching $PLIST to meet altool/App Store requirements..." | ||
|
|
||
| # PlistBuddy is more reliable for CI scripting. | ||
| # 'Set' updates the key if it exists. | ||
| /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString 1.4.0" "$PLIST" | ||
| /usr/libexec/PlistBuddy -c "Set :CFBundleVersion 1" "$PLIST" | ||
| /usr/libexec/PlistBuddy -c "Set :CFBundleName SoundFlow FFmpeg" "$PLIST" | ||
|
|
||
| # 'Add' creates the key if it doesn't exist (CMake sometimes omits MinimumOSVersion). | ||
| # We use '|| true' to ignore the error if it already exists. | ||
| /usr/libexec/PlistBuddy -c "Add :MinimumOSVersion string 12.0" "$PLIST" 2>/dev/null || true | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 11. The ios framework drops ios 11 support The plist patch declares MinimumOSVersion as 12.0 although the same workflow builds the framework with an iOS 11.0 deployment target. Successful artifacts therefore advertise a higher minimum version than the binary was built for, excluding iOS 11 from the distributed framework. Agent Prompt
|
||
|
|
||
| echo "Patched Info.plist contents:" | ||
| cat "$PLIST" | ||
| else | ||
| echo "Warning: Info.plist not found at expected path: $PLIST" | ||
| fi | ||
|
|
||
| - name: Analyze Dependencies | ||
| run: | | ||
| ARTIFACT_DIR="build/runtimes/ios-arm64/native" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -144,29 +144,29 @@ jobs: | |
| matrix: | ||
| include: | ||
| # Windows builds | ||
| - os: windows-latest | ||
| - os: windows-2025 | ||
| rid: win-x64 | ||
| platform: Windows | ||
| arch: x64 | ||
| cmake_target_arch: x64 | ||
| lib_extension: ".dll" | ||
| toolchain: "Visual Studio 17 2022" | ||
| toolchain: "Visual Studio 18 2026" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 10. Windows builds request the wrong toolchain The miniaudio Windows matrix requests the Visual Studio 2026 CMake generator while its tool-installation step explicitly installs Visual Studio 2019 Build Tools. If the runner does not separately provide the requested generator, every affected Windows configuration fails before compilation; the PortMidi workflow now makes the same generator request without installing it. Agent Prompt
|
||
|
|
||
| - os: windows-latest | ||
| - os: windows-2025 | ||
| rid: win-x86 | ||
| platform: Windows | ||
| arch: x86 | ||
| cmake_target_arch: Win32 | ||
| lib_extension: ".dll" | ||
| toolchain: "Visual Studio 17 2022" | ||
| toolchain: "Visual Studio 18 2026" | ||
|
|
||
| - os: windows-latest | ||
| - os: windows-2025 | ||
| rid: win-arm64 | ||
| platform: Windows | ||
| arch: ARM64 | ||
| cmake_target_arch: ARM64 | ||
| lib_extension: ".dll" | ||
| toolchain: "Visual Studio 17 2022" | ||
| toolchain: "Visual Studio 18 2026" | ||
|
|
||
| # Linux builds | ||
| - os: ubuntu-22.04 | ||
|
|
@@ -284,10 +284,16 @@ jobs: | |
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y cmake gcc g++ file binutils | ||
|
|
||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v6 | ||
| with: | ||
| distribution: 'temurin' | ||
| java-version: '17' | ||
|
|
||
| - name: Install Dependencies (Android) | ||
| if: matrix.platform == 'Android' | ||
| uses: android-actions/setup-android@v2 | ||
| uses: android-actions/setup-android@v4 | ||
|
|
||
| - name: Install Cross-Compilation tools (Linux) | ||
| if: matrix.platform == 'Linux' && (matrix.arch == 'armv7l' || matrix.arch == 'aarch64') | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -168,7 +168,7 @@ MA_API ma_device_config* sf_allocate_device_config(const ma_device_type deviceTy | |
|
|
||
| // Allocate memory for a decoder configuration struct. | ||
| MA_API ma_decoder_config *sf_allocate_decoder_config(const ma_format outputFormat, const ma_uint32 outputChannels, | ||
| const ma_uint32 outputSampleRate) { | ||
| const ma_uint32 outputSampleRate, const ma_uint32 seekPointCount) { | ||
| ma_decoder_config *pConfig = sf_create(ma_decoder_config); | ||
| if (pConfig == NULL) { | ||
| return NULL; | ||
|
|
@@ -177,6 +177,8 @@ MA_API ma_decoder_config *sf_allocate_decoder_config(const ma_format outputForma | |
| MA_ZERO_OBJECT(pConfig); | ||
| *pConfig = ma_decoder_config_init(outputFormat, outputChannels, outputSampleRate); | ||
|
|
||
| pConfig->seekPointCount = seekPointCount; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The native function now accepts Knowledge Base Used: Audio devices and MiniAudio backend Prompt To Fix With AIThis is a comment left during a code review.
Path: Native/miniaudio-backend/library.c
Line: 180
Comment:
**Seek settings differ by platform**
The native function now accepts `seekPointCount`, but the packaged Android, Intel macOS, and FreeBSD libraries were not updated. Those unchanged libraries still use the previous implementation, which does not apply the fourth argument. Rebuild the remaining runtime assets so users on those platforms also get the new seek-point setting.
**Knowledge Base Used:** [Audio devices and MiniAudio backend](https://app.greptile.com/lsxprime/-/custom-context/knowledge-base/lsxprime/soundflow/-/docs/audio-device-backend.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Holy fuck, I actually built the native libraries and forgot to replace them in the It’s not that I’m too lazy to do another There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right—the release workflow rebuilds the native libraries for all RIDs, replaces Tip: You can customize Greptile's behavior for this repo with |
||
|
|
||
| return pConfig; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,12 +27,21 @@ public sealed class FullDuplexDevice : AudioDevice, IDisposable | |
| public Mixer MasterMixer => PlaybackDevice.MasterMixer; | ||
|
|
||
| /// <summary> | ||
| /// Occurs when audio data is processed by the capture device. | ||
| /// Occurs when audio data is processed by either the capture or playback device. | ||
| /// Subscribers will receive both near-end (capture) and far-end (playback) frames. | ||
| /// </summary> | ||
| public event AudioProcessCallback? OnAudioProcessed | ||
| public new event AudioProcessCallback? OnAudioProcessed | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Knowledge Base Used: Audio devices and MiniAudio backend Prompt To Fix With AIThis is a comment left during a code review.
Path: Src/Abstracts/Devices/FullDuplexDevice.cs
Line: 33
Comment:
**Full-duplex callbacks disappear**
`FullDuplexDevice` hides the new base event with `new`, so subscribing through an `AudioDevice` reference attaches to a separate event that never fires. For example, `AudioDevice device = fullDuplexDevice; device.OnAudioProcessed += handler;` receives neither capture nor playback samples. Make the base event overridable and override its accessors, or forward both child events into the base event.
**Knowledge Base Used:** [Audio devices and MiniAudio backend](https://app.greptile.com/lsxprime/-/custom-context/knowledge-base/lsxprime/soundflow/-/docs/audio-device-backend.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly. |
||
| { | ||
| add => CaptureDevice.OnAudioProcessed += value; | ||
| remove => CaptureDevice.OnAudioProcessed -= value; | ||
| add | ||
| { | ||
| CaptureDevice.OnAudioProcessed += value; | ||
| PlaybackDevice.OnAudioProcessed += value; | ||
|
Comment on lines
+33
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 9. Base-typed duplex listeners hear nothing FullDuplexDevice hides the new base OnAudioProcessed event with a separate forwarding event instead of overriding subscription behavior. A listener holding the duplex device as AudioDevice subscribes to its never-raised base event, rather than either child device's capture or playback event. Agent Prompt
|
||
| } | ||
| remove | ||
| { | ||
| CaptureDevice.OnAudioProcessed -= value; | ||
| PlaybackDevice.OnAudioProcessed -= value; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -87,4 +96,12 @@ public override void Dispose() | |
|
|
||
| IsDisposed = true; | ||
| } | ||
| } | ||
|
|
||
| /// <inheritdoc /> | ||
| internal override Delegate[] GetEventSubscribers() | ||
| { | ||
| // Subscribers are routed to the child devices, so we retrieve them from there. | ||
| // Returning CaptureDevice's list is sufficient as both will have the same subscribers. | ||
| return CaptureDevice.GetEventSubscribers(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
12. Future codec releases keep an old version
🐞 Bug⚙ MaintainabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools