Visualization Experiment: Test out projectM

This was just an experiment, and was hashed in to test it out. It does
not look like it would be a very efficient thing to ship this in the
main app at all, especially since the collection of presets is so dang
huge. It was also never meant to replace the existing visualizations,
but instead as another option. One of the things from this branch will
make it into the final: Optional nullability of the Visualization
Manager parameters, since technically they're both checked on call.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-03-12 02:47:41 -07:00
parent e7779278bd
commit 341e27b3b6
34 changed files with 2138 additions and 6 deletions

5
.gitignore vendored
View file

@ -53,3 +53,8 @@ Xcode-config/SENTRY_SETTINGS.xcconfig
/ThirdParty/vorbis/lib/libvorbisfile.3.dylib /ThirdParty/vorbis/lib/libvorbisfile.3.dylib
/ThirdParty/vorbis/lib/libvorbis.0.dylib /ThirdParty/vorbis/lib/libvorbis.0.dylib
/ThirdParty/soxr/lib/libsoxr.0.dylib /ThirdParty/soxr/lib/libsoxr.0.dylib
/ThirdParty/libprojectM/lib/libprojectM-4.4.dylib
/ThirdParty/libprojectM/lib/libprojectM-4-playlist.4.dylib
/ThirdParty/libprojectM/lib/libboost_system.dylib
/ThirdParty/libprojectM/lib/libboost_atomic.dylib
/ThirdParty/libprojectM/lib/libboost_filesystem.dylib

6
.gitmodules vendored
View file

@ -19,3 +19,9 @@
[submodule "Frameworks/libsidplayfp/sidplayfp"] [submodule "Frameworks/libsidplayfp/sidplayfp"]
path = Frameworks/libsidplayfp/sidplayfp path = Frameworks/libsidplayfp/sidplayfp
url = https://github.com/kode54/libsidplayfp.git url = https://github.com/kode54/libsidplayfp.git
[submodule "ThirdParty/libprojectM/subprojects/presets-milkdrop-texture-pack"]
path = ThirdParty/libprojectM/subprojects/presets-milkdrop-texture-pack
url = https://github.com/projectM-visualizer/presets-milkdrop-texture-pack.git
[submodule "ThirdParty/libprojectM/subprojects/presets/presets-cream-of-the-crop"]
path = ThirdParty/libprojectM/subprojects/presets/presets-cream-of-the-crop
url = https://github.com/projectM-visualizer/presets-cream-of-the-crop.git

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22113.1" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22113.1"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>

View file

@ -97,6 +97,8 @@
830C37A127B95E3000E02BB0 /* Equalizer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 830C379F27B95E3000E02BB0 /* Equalizer.xib */; }; 830C37A127B95E3000E02BB0 /* Equalizer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 830C379F27B95E3000E02BB0 /* Equalizer.xib */; };
830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 830C37A427B95EB300E02BB0 /* EqualizerWindowController.m */; }; 830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 830C37A427B95EB300E02BB0 /* EqualizerWindowController.m */; };
830C37FC27B9956C00E02BB0 /* analyzer.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C37F227B9956C00E02BB0 /* analyzer.c */; }; 830C37FC27B9956C00E02BB0 /* analyzer.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C37F227B9956C00E02BB0 /* analyzer.c */; };
830EDD1B2D813DEA00988EA8 /* libprojectM-4.4.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E9EEBA2D80634600F1D22D /* libprojectM-4.4.dylib */; };
830EDD1C2D813DF600988EA8 /* libprojectM-4-playlist.4.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E9EEB92D80634600F1D22D /* libprojectM-4-playlist.4.dylib */; };
831B99BF27C23E88005A969B /* Cog.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 831B99BE27C23E88005A969B /* Cog.sdef */; }; 831B99BF27C23E88005A969B /* Cog.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 831B99BE27C23E88005A969B /* Cog.sdef */; };
83256B68286661FC0036D9C0 /* libmpg123.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; }; 83256B68286661FC0036D9C0 /* libmpg123.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; };
83256B69286661FC0036D9C0 /* libmpg123.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83256B69286661FC0036D9C0 /* libmpg123.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
@ -181,6 +183,17 @@
83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; }; 83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; };
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; }; 83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
83E9A0D02D804A1800F1D22D /* ProjectMView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E9A0CF2D804A1800F1D22D /* ProjectMView.m */; };
83E9EEB32D805C5300F1D22D /* textures in Copy Files */ = {isa = PBXBuildFile; fileRef = 83E9EEB22D805C5300F1D22D /* textures */; };
83E9EEB52D805C7B00F1D22D /* presets in Copy Files */ = {isa = PBXBuildFile; fileRef = 83E9EEB42D805C7B00F1D22D /* presets */; };
83E9EEBB2D80634600F1D22D /* libboost_atomic.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E9EEB62D80634600F1D22D /* libboost_atomic.dylib */; };
83E9EEBC2D80634600F1D22D /* libboost_system.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E9EEB82D80634600F1D22D /* libboost_system.dylib */; };
83E9EEBE2D80634600F1D22D /* libboost_filesystem.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E9EEB72D80634600F1D22D /* libboost_filesystem.dylib */; };
83E9EEC02D80639E00F1D22D /* libprojectM-4.4.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83E9EEBA2D80634600F1D22D /* libprojectM-4.4.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83E9EEC12D8063A100F1D22D /* libboost_system.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83E9EEB82D80634600F1D22D /* libboost_system.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83E9EEC22D8063A400F1D22D /* libboost_atomic.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83E9EEB62D80634600F1D22D /* libboost_atomic.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83E9EEC32D8063A700F1D22D /* libboost_filesystem.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83E9EEB72D80634600F1D22D /* libboost_filesystem.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83E9EEC42D8063AD00F1D22D /* libprojectM-4-playlist.4.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83E9EEB92D80634600F1D22D /* libprojectM-4-playlist.4.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 83F9FFEE2D6EB75B00026576 /* Sentry */; }; 83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 83F9FFEE2D6EB75B00026576 /* Sentry */; };
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
@ -669,6 +682,8 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 7; dstSubfolderSpec = 7;
files = ( files = (
83E9EEB52D805C7B00F1D22D /* presets in Copy Files */,
83E9EEB32D805C5300F1D22D /* textures in Copy Files */,
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in Copy Files */, ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in Copy Files */,
); );
name = "Copy Files"; name = "Copy Files";
@ -717,6 +732,11 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
83E9EEC32D8063A700F1D22D /* libboost_filesystem.dylib in CopyFiles */,
83E9EEC22D8063A400F1D22D /* libboost_atomic.dylib in CopyFiles */,
83E9EEC12D8063A100F1D22D /* libboost_system.dylib in CopyFiles */,
83E9EEC42D8063AD00F1D22D /* libprojectM-4-playlist.4.dylib in CopyFiles */,
83E9EEC02D80639E00F1D22D /* libprojectM-4.4.dylib in CopyFiles */,
836DF617298F6F1700CD0580 /* libsoxr.0.dylib in CopyFiles */, 836DF617298F6F1700CD0580 /* libsoxr.0.dylib in CopyFiles */,
836EF0E127BB98AB00BF35B2 /* libopusfile.0.dylib in CopyFiles */, 836EF0E127BB98AB00BF35B2 /* libopusfile.0.dylib in CopyFiles */,
836EF0E027BB98A800BF35B2 /* libopus.0.dylib in CopyFiles */, 836EF0E027BB98A800BF35B2 /* libopus.0.dylib in CopyFiles */,
@ -1044,6 +1064,15 @@
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; }; 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; }; 83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPT.xcodeproj; path = Plugins/OpenMPT/OpenMPT.xcodeproj; sourceTree = "<group>"; }; 83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPT.xcodeproj; path = Plugins/OpenMPT/OpenMPT.xcodeproj; sourceTree = "<group>"; };
83E9A0CE2D8049FA00F1D22D /* ProjectMView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProjectMView.h; path = Visualization/ProjectMView.h; sourceTree = "<group>"; };
83E9A0CF2D804A1800F1D22D /* ProjectMView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ProjectMView.m; path = Visualization/ProjectMView.m; sourceTree = "<group>"; };
83E9EEB22D805C5300F1D22D /* textures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = textures; path = "ThirdParty/libprojectM/subprojects/presets-milkdrop-texture-pack/textures"; sourceTree = "<group>"; };
83E9EEB42D805C7B00F1D22D /* presets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = presets; path = ThirdParty/libprojectM/subprojects/presets; sourceTree = "<group>"; };
83E9EEB62D80634600F1D22D /* libboost_atomic.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libboost_atomic.dylib; path = ThirdParty/libprojectM/lib/libboost_atomic.dylib; sourceTree = "<group>"; };
83E9EEB72D80634600F1D22D /* libboost_filesystem.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libboost_filesystem.dylib; path = ThirdParty/libprojectM/lib/libboost_filesystem.dylib; sourceTree = "<group>"; };
83E9EEB82D80634600F1D22D /* libboost_system.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libboost_system.dylib; path = ThirdParty/libprojectM/lib/libboost_system.dylib; sourceTree = "<group>"; };
83E9EEB92D80634600F1D22D /* libprojectM-4-playlist.4.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libprojectM-4-playlist.4.dylib"; path = "ThirdParty/libprojectM/lib/libprojectM-4-playlist.4.dylib"; sourceTree = "<group>"; };
83E9EEBA2D80634600F1D22D /* libprojectM-4.4.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libprojectM-4.4.dylib"; path = "ThirdParty/libprojectM/lib/libprojectM-4.4.dylib"; sourceTree = "<group>"; };
83F9D7F11A884B44007ABEC2 /* SilenceDecoder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SilenceDecoder.xcodeproj; path = Plugins/SilenceDecoder/SilenceDecoder.xcodeproj; sourceTree = "<group>"; }; 83F9D7F11A884B44007ABEC2 /* SilenceDecoder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SilenceDecoder.xcodeproj; path = Plugins/SilenceDecoder/SilenceDecoder.xcodeproj; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8E07AB760AAC930B00A4B32F /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PreferencesController.h; path = Preferences/PreferencesController.h; sourceTree = "<group>"; }; 8E07AB760AAC930B00A4B32F /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PreferencesController.h; path = Preferences/PreferencesController.h; sourceTree = "<group>"; };
@ -1080,6 +1109,11 @@
8355D6B8180613FB00D05687 /* Security.framework in Frameworks */, 8355D6B8180613FB00D05687 /* Security.framework in Frameworks */,
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
83256B68286661FC0036D9C0 /* libmpg123.0.dylib in Frameworks */, 83256B68286661FC0036D9C0 /* libmpg123.0.dylib in Frameworks */,
830EDD1C2D813DF600988EA8 /* libprojectM-4-playlist.4.dylib in Frameworks */,
830EDD1B2D813DEA00988EA8 /* libprojectM-4.4.dylib in Frameworks */,
83E9EEBB2D80634600F1D22D /* libboost_atomic.dylib in Frameworks */,
83E9EEBC2D80634600F1D22D /* libboost_system.dylib in Frameworks */,
83E9EEBE2D80634600F1D22D /* libboost_filesystem.dylib in Frameworks */,
17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */, 17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */,
835FAC7F27BCDF5B00BA8562 /* libavif.a in Frameworks */, 835FAC7F27BCDF5B00BA8562 /* libavif.a in Frameworks */,
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */, 83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */,
@ -1144,6 +1178,11 @@
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83E9EEB62D80634600F1D22D /* libboost_atomic.dylib */,
83E9EEB72D80634600F1D22D /* libboost_filesystem.dylib */,
83E9EEB82D80634600F1D22D /* libboost_system.dylib */,
83E9EEB92D80634600F1D22D /* libprojectM-4-playlist.4.dylib */,
83E9EEBA2D80634600F1D22D /* libprojectM-4.4.dylib */,
838A33732D06A9B100D0D770 /* librubberband.3.dylib */, 838A33732D06A9B100D0D770 /* librubberband.3.dylib */,
836DF616298F6EC400CD0580 /* libsoxr.0.dylib */, 836DF616298F6EC400CD0580 /* libsoxr.0.dylib */,
83256B672866617F0036D9C0 /* libmpg123.0.dylib */, 83256B672866617F0036D9C0 /* libmpg123.0.dylib */,
@ -1468,6 +1507,8 @@
29B97314FDCFA39411CA2CEA /* Cog */ = { 29B97314FDCFA39411CA2CEA /* Cog */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83E9EEB42D805C7B00F1D22D /* presets */,
83E9EEB22D805C5300F1D22D /* textures */,
0A1B412E286F6301008A6A44 /* Localizable.stringsdict */, 0A1B412E286F6301008A6A44 /* Localizable.stringsdict */,
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */, 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */,
83859520234FEB35004E9946 /* Cog.entitlements */, 83859520234FEB35004E9946 /* Cog.entitlements */,
@ -1800,6 +1841,8 @@
838A33812D06CF4100D0D770 /* SpectrumWindowController.h */, 838A33812D06CF4100D0D770 /* SpectrumWindowController.h */,
838A33822D06CF4100D0D770 /* SpectrumWindowController.m */, 838A33822D06CF4100D0D770 /* SpectrumWindowController.m */,
8377C66427B8CF7A00E8BC0F /* VisualizationController.h */, 8377C66427B8CF7A00E8BC0F /* VisualizationController.h */,
83E9A0CE2D8049FA00F1D22D /* ProjectMView.h */,
83E9A0CF2D804A1800F1D22D /* ProjectMView.m */,
); );
name = Visualization; name = Visualization;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2545,6 +2588,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
83E9A0D02D804A1800F1D22D /* ProjectMView.m in Sources */,
83A3B734283AE89000CC6593 /* ColorToValueTransformer.m in Sources */, 83A3B734283AE89000CC6593 /* ColorToValueTransformer.m in Sources */,
8D11072D0486CEB800E47090 /* main.m in Sources */, 8D11072D0486CEB800E47090 /* main.m in Sources */,
8E75757109F31D5A0080F1EE /* DNDArrayController.m in Sources */, 8E75757109F31D5A0080F1EE /* DNDArrayController.m in Sources */,
@ -2956,7 +3000,10 @@
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = ThirdParty/avif/include; HEADER_SEARCH_PATHS = (
ThirdParty/avif/include,
ThirdParty/libprojectM/include,
);
IBC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES; IBC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES;
IBSC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES; IBSC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES;
INFOPLIST_FILE = Info.plist; INFOPLIST_FILE = Info.plist;
@ -2975,6 +3022,7 @@
"$(PROJECT_DIR)/ThirdParty/soxr/lib", "$(PROJECT_DIR)/ThirdParty/soxr/lib",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
"$(PROJECT_DIR)/ThirdParty/rubberband/lib", "$(PROJECT_DIR)/ThirdParty/rubberband/lib",
"$(PROJECT_DIR)/ThirdParty/libprojectM/lib",
); );
OTHER_CFLAGS = ( OTHER_CFLAGS = (
"-D__MACOSX__", "-D__MACOSX__",
@ -3015,7 +3063,10 @@
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/ThirdParty/Frameworks"; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/ThirdParty/Frameworks";
GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_ENABLE_OBJC_EXCEPTIONS = YES;
HEADER_SEARCH_PATHS = ThirdParty/avif/include; HEADER_SEARCH_PATHS = (
ThirdParty/avif/include,
ThirdParty/libprojectM/include,
);
IBC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES; IBC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES;
IBSC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES; IBSC_COMPILER_USE_NIBKEYEDARCHIVER_FOR_MACOS = YES;
INFOPLIST_FILE = Info.plist; INFOPLIST_FILE = Info.plist;
@ -3034,6 +3085,7 @@
"$(PROJECT_DIR)/ThirdParty/soxr/lib", "$(PROJECT_DIR)/ThirdParty/soxr/lib",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
"$(PROJECT_DIR)/ThirdParty/rubberband/lib", "$(PROJECT_DIR)/ThirdParty/rubberband/lib",
"$(PROJECT_DIR)/ThirdParty/libprojectM/lib",
); );
OTHER_CFLAGS = ( OTHER_CFLAGS = (
"-D__MACOSX__", "-D__MACOSX__",

View file

@ -0,0 +1,99 @@
/**
* @file audio.h
* @copyright 2003-2023 projectM Team
* @brief Functions to pass in audio data to libprojectM.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Returns the maximum number of audio samples that can be stored.
*
* Each PCM data UpdateMeshSize should not exceed this number of samples. If more samples
* are added, only this number of samples is stored and the remainder discarded.
*
* @return The number of audio samples that are stored, per channel.
*/
PROJECTM_EXPORT unsigned int projectm_pcm_get_max_samples();
/**
* @brief Adds 32-bit floating-point audio samples.
*
* This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data, duplicating the channel.
*
* If stereo, the channel order in samples is LRLRLR.
*
* @param instance The projectM instance handle.
* @param samples An array of PCM samples.
* Each sample is expected to be within the range -1 to 1.
* @param count The number of audio samples in a channel.
* @param channels If the buffer is mono or stereo.
* Can be PROJECTM_MONO or PROJECTM_STEREO.
*/
PROJECTM_EXPORT void projectm_pcm_add_float(projectm_handle instance, const float* samples,
unsigned int count, projectm_channels channels);
/**
* @brief Adds 16-bit integer audio samples.
*
* This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data, duplicating the channel.
*
* If stereo, the channel order in samples is LRLRLR.
*
* @param instance The projectM instance handle.
* @param samples An array of PCM samples.
* @param count The number of audio samples in a channel.
* @param channels If the buffer is mono or stereo.
* Can be PROJECTM_MONO or PROJECTM_STEREO.
*/
PROJECTM_EXPORT void projectm_pcm_add_int16(projectm_handle instance, const int16_t* samples,
unsigned int count, projectm_channels channels);
/**
* @brief Adds 8-bit unsigned integer audio samples.
*
* This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data, duplicating the channel.
*
* If stereo, the channel order in samples is LRLRLR.
*
* @param instance The projectM instance handle.
* @param samples An array of PCM samples.
* @param count The number of audio samples in a channel.
* @param channels If the buffer is mono or stereo.
* Can be PROJECTM_MONO or PROJECTM_STEREO.
*/
PROJECTM_EXPORT void projectm_pcm_add_uint8(projectm_handle instance, const uint8_t* samples,
unsigned int count, projectm_channels channels);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,89 @@
/**
* @file callbacks.h
* @copyright 2003-2023 projectM Team
* @brief Functions and prototypes for projectM callbacks.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Callback function that is executed whenever projectM wants to switch to a new preset.
*
* @param is_hard_cut If true, the transition was triggered by a beat-driven event.
* @param user_data A user-defined data pointer that was provided when registering the callback,
* e.g. context information.
*/
typedef void (*projectm_preset_switch_requested_event)(bool is_hard_cut, void* user_data);
/**
* @brief Callback function that is executed if a preset change failed.
*
* The message and filename pointers are only valid inside the callback. Make a copy if these values
* need to be retained for later use.
*
* @param preset_filename The filename of the failed preset.
* @param message The error message.
* @param user_data A user-defined data pointer that was provided when registering the callback,
* e.g. context information.
*/
typedef void (*projectm_preset_switch_failed_event)(const char* preset_filename,
const char* message, void* user_data);
/**
* @brief Sets a callback function that will be called when a preset change is requested.
*
* Only one callback can be registered per projectM instance. To remove the callback, use NULL.
*
* @param instance The projectM instance handle.
* @param callback A pointer to the callback function.
* @param user_data A pointer to any data that will be sent back in the callback, e.g. context
* information.
*/
PROJECTM_EXPORT void projectm_set_preset_switch_requested_event_callback(projectm_handle instance,
projectm_preset_switch_requested_event callback,
void* user_data);
/**
* @brief Sets a callback function that will be called when a preset change failed.
*
* Only one callback can be registered per projectM instance. To remove the callback, use NULL.
*
* @param instance The projectM instance handle.
* @param callback A pointer to the callback function.
* @param user_data A pointer to any data that will be sent back in the callback, e.g. context
* information.
*/
PROJECTM_EXPORT void projectm_set_preset_switch_failed_event_callback(projectm_handle instance,
projectm_preset_switch_failed_event callback,
void* user_data);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,135 @@
/**
* @file core.h
* @copyright 2003-2023 projectM Team
* @brief Core functions to instantiate, destroy and control projectM.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Creates a new projectM instance.
*
* If this function returns NULL, in most cases the OpenGL context is not initialized, not made
* current or insufficient to render projectM visuals.
*
* @return A projectM handle for the newly created instance that must be used in subsequent API calls.
* NULL if the instance could not be created successfully.
*/
PROJECTM_EXPORT projectm_handle projectm_create();
/**
* @brief Destroys the given instance and frees the resources.
*
* After destroying the handle, it must not be used for any other calls to the API.
*
* @param instance A handle returned by projectm_create() or projectm_create_settings().
*/
PROJECTM_EXPORT void projectm_destroy(projectm_handle instance);
/**
* @brief Loads a preset from the given filename/URL.
*
* Ideally, the filename should be given as a standard local path. projectM also supports loading
* "file://" URLs. Additionally, the special filename "idle://" can be used to load the default
* idle preset, displaying the "M" logo.
*
* Other URL schemas aren't supported and will cause a loading error.
*
* If the preset can't be loaded, no switch takes place and the current preset will continue to
* be displayed. Note that if there's a transition in progress when calling this function, the
* transition will be finished immediately, even if the new preset can't be loaded.
*
* @param instance The projectM instance handle.
* @param filename The preset filename or URL to load.
* @param smooth_transition If true, the new preset is smoothly blended over.
*/
PROJECTM_EXPORT void projectm_load_preset_file(projectm_handle instance, const char* filename,
bool smooth_transition);
/**
* @brief Loads a preset from the data pointer.
*
* Currently, the preset data is assumed to be in Milkdrop format.
*
* If the preset can't be loaded, no switch takes place and the current preset will continue to
* be displayed. Note that if there's a transition in progress when calling this function, the
* transition will be finished immediately, even if the new preset can't be loaded.
*
* @param instance The projectM instance handle.
* @param data The preset contents to load.
* @param smooth_transition If true, the new preset is smoothly blended over.
*/
PROJECTM_EXPORT void projectm_load_preset_data(projectm_handle instance, const char* data,
bool smooth_transition);
/**
* @brief Reloads all textures.
*
* Calling this method will clear and reload all textures, including the main rendering texture.
* Can cause a small delay/lag in rendering. Only use if texture paths were changed.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_reset_textures(projectm_handle instance);
/**
* @brief Returns the runtime library version components as individual integers.
*
* Components which aren't required can be set to NULL.
*
* @param major A pointer to an int that will be set to the major version.
* @param minor A pointer to an int that will be set to the minor version.
* @param patch A pointer to an int that will be set to the patch version.
*/
PROJECTM_EXPORT void projectm_get_version_components(int* major, int* minor, int* patch);
/**
* @brief Returns the runtime library version as a string.
*
* Remember to call @a projectm_free_string() on the returned pointer if the data is no longer
* needed.
*
* @return The library version in the format major.minor.patch.
*/
PROJECTM_EXPORT char* projectm_get_version_string();
/**
* @brief Returns the VCS revision from which the projectM library was built.
*
* Can be any text, will mostly contain a Git commit hash. Useful to report bugs.
*
* Remember to call @a projectm_free_string() on the returned pointer if the data is no longer
* needed.
*
* @return The VCS revision number the projectM library was built from.
*/
PROJECTM_EXPORT char* projectm_get_vcs_version_string();
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,55 @@
/**
* @file debug.h
* @copyright 2003-2023 projectM Team
* @brief Debug functions for both libprojectM and preset developers.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Writes a .bmp main texture dump after rendering the next main texture, before shaders are applied.
*
* If no file name is given, the image is written to the current working directory
* and will be named named "frame_texture_contents-YYYY-mm-dd-HH:MM:SS-frame.bmp".
*
* Note this is the main texture contents, not the final rendering result. If the active preset
* uses a composite shader, the dumped image will not have it applied. The main texture is what is
* passed over to the next frame, the composite shader is only applied to the display framebuffer
* after updating the main texture.
*
* To capture the actual output, dump the contents of the main framebuffer after calling
* @a projectm_render_frame() on the application side.
*
* @param instance The projectM instance handle.
* @param output_file The filename to write the dump to or NULL.
*/
PROJECTM_EXPORT void projectm_write_debug_image_on_next_frame(projectm_handle instance, const char* output_file);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,57 @@
/**
* @file memory.h
* @copyright 2003-2023 projectM Team
* @brief Memory allocation/deallocation helpers.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Allocates memory for a string and returns the pointer.
*
* To free the allocated memory, call projectm_free_string(). Do not use free()!
*
* @return A pointer to a zero-initialized memory area.
*/
PROJECTM_EXPORT char* projectm_alloc_string(unsigned int length);
/**
* @brief Frees the memory of an allocated string.
*
* <p>Frees the memory allocated by a call to projectm_alloc_string() or any
* (const) char* pointers returned by a projectM API call.</p>
*
* <p>Do not use free() to delete the pointer!</p>
*
* @param str A pointer returned by projectm_alloc_string().
*/
PROJECTM_EXPORT void projectm_free_string(const char* str);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,278 @@
/**
* @file parameters.h
* @copyright 2003-2023 projectM Team
* @brief Functions to set and retrieve all sorts of projectM parameters and setting.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the texture search paths.
*
* Calling this method will clear and reload all textures, including the main rendering texture.
* Can cause a small delay/lag in rendering. Only use if texture paths were changed.
*
* @param instance The projectM instance handle.
* @param texture_search_paths A list of texture search paths.
* @param count The number of paths in the list.
*/
PROJECTM_EXPORT void projectm_set_texture_search_paths(projectm_handle instance,
const char** texture_search_paths,
size_t count);
/**
* @brief Sets the beat sensitivity.
*
* The beat sensitivity to be used.
*
* @param instance The projectM instance handle.
* @param sensitivity The sensitivity setting.
*/
PROJECTM_EXPORT void projectm_set_beat_sensitivity(projectm_handle instance, float sensitivity);
/**
* @brief Returns the beat sensitivity.
* @param instance The projectM instance handle.
* @return The current sensitivity setting.
*/
PROJECTM_EXPORT float projectm_get_beat_sensitivity(projectm_handle instance);
/**
* @brief Sets the minimum display time before a hard cut can happen.
*
* <p>Hard cuts are beat-sensitive preset transitions, immediately changing from
* one preset to the next without a smooth blending period.</p>
*
* <p>Set this to a higher value than preset duration to disable hard cuts.</p>
*
* @param instance The projectM instance handle.
* @param seconds Minimum number of seconds the preset will be displayed before a hard cut.
*/
PROJECTM_EXPORT void projectm_set_hard_cut_duration(projectm_handle instance, double seconds);
/**
* @brief Returns the minimum display time before a hard cut can happen.
* @param instance The projectM instance handle.
* @return The minimum number of seconds the preset will be displayed before a hard cut.
*/
PROJECTM_EXPORT double projectm_get_hard_cut_duration(projectm_handle instance);
/**
* @brief Enables or disables hard cuts.
*
* Even if enabled, the hard cut duration must be set to a value lower than the preset duration
* to work properly.
*
* @param instance The projectM instance handle.
* @param enabled True to enable hard cuts, false to disable.
*/
PROJECTM_EXPORT void projectm_set_hard_cut_enabled(projectm_handle instance, bool enabled);
/**
* @brief Returns whether hard cuts are enabled or not.
* @param instance The projectM instance handle.
* @return True if hard cuts are enabled, false otherwise.
*/
PROJECTM_EXPORT bool projectm_get_hard_cut_enabled(projectm_handle instance);
/**
* @brief Sets the hard cut volume sensitivity.
*
* The beat detection volume difference that must be surpassed to trigger a hard cut.
*
* @param instance The projectM instance handle.
* @param sensitivity The volume threshold that triggers a hard cut if surpassed.
*/
PROJECTM_EXPORT void projectm_set_hard_cut_sensitivity(projectm_handle instance, float sensitivity);
/**
* @brief Returns the current hard cut sensitivity.
* @param instance The projectM instance handle.
* @return The current hard cut sensitivity.
*/
PROJECTM_EXPORT float projectm_get_hard_cut_sensitivity(projectm_handle instance);
/**
* @brief Sets the time in seconds for a soft transition between two presets.
*
* During a soft cut, both presets are rendered and slowly transitioned from one
* to the other.
*
* @param instance The projectM instance handle.
* @param seconds Time in seconds it takes to smoothly transition from one preset to another.
*/
PROJECTM_EXPORT void projectm_set_soft_cut_duration(projectm_handle instance, double seconds);
/**
* @brief Returns the time in seconds for a soft transition between two presets.
* @param instance The projectM instance handle.
* @return Time in seconds it takes to smoothly transition from one preset to another.
*/
PROJECTM_EXPORT double projectm_get_soft_cut_duration(projectm_handle instance);
/**
* @brief Sets the preset display duration before switching to the next using a soft cut.
*
* This can be considered as the maximum time a preset is displayed. If this time is reached,
* a smooth cut will be initiated. A hard cut, if any, will always happen before this time.
*
* @param instance The projectM instance handle.
* @param seconds The number of seconds a preset will be displayed before the next is shown.
*/
PROJECTM_EXPORT void projectm_set_preset_duration(projectm_handle instance, double seconds);
/**
* @brief Returns the preset display duration before switching to the next using a soft cut.
*
* This can be considered as the maximum time a preset is displayed. If this time is reached,
* a smooth cut will be initiated. A hard cut, if any, will always happen before this time.
*
* @param instance The projectM instance handle.
* @return The currently set preset display duration in seconds.
*/
PROJECTM_EXPORT double projectm_get_preset_duration(projectm_handle instance);
/**
* @brief Sets the per-pixel equation mesh size in units.
* Will internally be clamped to [8,300] in each axis. If any dimension is set to an odd value, it will be incremented by 1
* so only multiples of two are used.
* @param instance The projectM instance handle.
* @param width The new width of the mesh.
* @param height The new height of the mesh.
*/
PROJECTM_EXPORT void projectm_set_mesh_size(projectm_handle instance, size_t width, size_t height);
/**
* @brief Returns the per-pixel equation mesh size in units.
* @param instance The projectM instance handle.
* @param width The width of the mesh.
* @param height The height of the mesh.
*/
PROJECTM_EXPORT void projectm_get_mesh_size(projectm_handle instance, size_t* width, size_t* height);
/**
* @brief Sets the current/average frames per second.
*
* Applications running projectM should UpdateMeshSize this value regularly and set it to the calculated
* (and possibly averaged) FPS value the output rendered with. The value is passed on to presets,
* which may choose to use it for calculations. It is not used in any other way by the library.
*
* @param instance The projectM instance handle.
* @param fps The current FPS value projectM is running with.
*/
PROJECTM_EXPORT void projectm_set_fps(projectm_handle instance, int32_t fps);
/**
* @brief Returns the current/average frames per second.
*
* This value needs to be set by the application. If it wasn't set, a default value of 60 is used.
*
* @param instance The projectM instance handle.
* @return The current/average frames per second.
*/
PROJECTM_EXPORT int32_t projectm_get_fps(projectm_handle instance);
/**
* @brief Enabled or disables aspect ratio correction in presets that support it.
*
* This sets a flag presets can use to aspect-correct rendered shapes, which otherwise would
* be distorted if the viewport isn't exactly square.
*
* @param instance The projectM instance handle.
* @param enabled True to enable aspect correction, false to disable it.
*/
PROJECTM_EXPORT void projectm_set_aspect_correction(projectm_handle instance, bool enabled);
/**
* @brief Returns whether aspect ratio correction is enabled or not.
* @param instance The projectM instance handle.
* @return True if aspect ratio correction is enabled, false otherwise.
*/
PROJECTM_EXPORT bool projectm_get_aspect_correction(projectm_handle instance);
/**
* @brief Sets the "easter egg" value.
*
* <p>This doesn't enable any fancy feature, it only influences the randomized display time of presets. It's
* passed as the "sigma" value of the gaussian random number generator used to determine the maximum display time,
* effectively multiplying the generated number of seconds by this amount.</p>
*
* <p>See function sampledPresetDuration() of the TimeKeeper class on how it is used.</p>
*
* @param instance The projectM instance handle.
* @param value The new "easter egg" value. Must be greater than zero, otherwise a default sigma value of 1.0 will be used.
*/
PROJECTM_EXPORT void projectm_set_easter_egg(projectm_handle instance, float value);
/**
* @brief Returns the current "easter egg" value.
* @param instance The projectM instance handle.
* @return The current "easter egg" value.
*/
PROJECTM_EXPORT float projectm_get_easter_egg(projectm_handle instance);
/**
* @brief Locks or unlocks the current preset.
*
* Locking effectively disables automatic preset transitions, both hard and soft cuts. Programmatic
* preset switches will still be executed.
*
* @param instance The projectM instance handle.
* @param lock True to lock the current preset, false to enable automatic transitions.
*/
PROJECTM_EXPORT void projectm_set_preset_locked(projectm_handle instance, bool lock);
/**
* @brief Returns whether the current preset is locked or not.
* @param instance The projectM instance handle.
* @return True if the preset lock is enabled, false otherwise.
*/
PROJECTM_EXPORT bool projectm_get_preset_locked(projectm_handle instance);
/**
* @brief Sets the current viewport size in pixels.
*
* Calling this function will reset the OpenGL renderer.
*
* @param instance The projectM instance handle.
* @param width New viewport width in pixels.
* @param height New viewport height in pixels.
*/
PROJECTM_EXPORT void projectm_set_window_size(projectm_handle instance, size_t width, size_t height);
/**
* @brief Returns the current viewport size in pixels.
* @param instance The projectM instance handle.
* @param width Valid pointer to a size_t variable that will receive the window width value.
* @param height Valid pointer to a size_t variable that will receive the window height value.
*/
PROJECTM_EXPORT void projectm_get_window_size(projectm_handle instance, size_t* width, size_t* height);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,34 @@
/**
* @file playlist.h
* @copyright 2003-2023 projectM Team
* @brief Optional playlist API for libprojectM.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/playlist_callbacks.h"
#include "projectM-4/playlist_core.h"
#include "projectM-4/playlist_filter.h"
#include "projectM-4/playlist_items.h"
#include "projectM-4/playlist_memory.h"
#include "projectM-4/playlist_playback.h"
#include "projectM-4/playlist_types.h"

View file

@ -0,0 +1,104 @@
/**
* @file playlist_callbacks.h
* @copyright 2003-2023 projectM Team
* @brief Functions and prototypes for projectM playlist callbacks.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/playlist_types.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Callback function that is executed on each preset change.
*
* Can be used for example to UpdateMeshSize the application window title. Applications must not
* switch presets inside this callback, as it can lead to infinite recursion.
*
* @param is_hard_cut True if the preset was switched using a hard cut via beat detection.
* @param index The playlist index of the new preset.
* @param user_data A user-defined data pointer that was provided when registering the callback,
* e.g. context information.
*/
typedef void (*projectm_playlist_preset_switched_event)(bool is_hard_cut, unsigned int index,
void* user_data);
/**
* @brief Callback function that is executed if a preset change failed too often.
*
* Similar to the projectM API function, but will only be called if the preset switch failed
* multiple times in a row, e.g. due to missing files or broken presets. The application should
* decide what action to take.
*
* @note Do NOT call any functions that switch presets inside the callback, at it might
* lead to infinite recursion and thus a stack overflow!
* @note The message pointer is only valid inside the callback. Make a copy if it need to be
* retained for later use.
* @param preset_filename The filename of the failed preset.
* @param message The last error message.
* @param user_data A user-defined data pointer that was provided when registering the callback,
* e.g. context information.
*/
typedef void (*projectm_playlist_preset_switch_failed_event)(const char* preset_filename,
const char* message, void* user_data);
/**
* @brief Sets a callback function that will be called when a preset changes.
*
* Only one callback can be registered per playlist instance. To remove the callback, use NULL.
*
* @param instance The playlist manager instance.
* @param callback A pointer to the callback function.
* @param user_data A pointer to any data that will be sent back in the callback, e.g. context
* information.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_set_preset_switched_event_callback(projectm_playlist_handle instance,
projectm_playlist_preset_switched_event callback,
void* user_data);
/**
* @brief Sets a callback function that will be called when a preset change failed.
*
* Only one callback can be registered per projectM instance. To remove the callback, use NULL.
*
* If the application want to receive projectM's analogous callback directly, use the
* projectm_set_preset_switch_failed_event_callback() function after calling
* projectm_playlist_create() or projectm_playlist_connect(), respectively, as these will both
* override the callback set in projectM.
*
* @param instance The playlist manager instance.
* @param callback A pointer to the callback function.
* @param user_data A pointer to any data that will be sent back in the callback, e.g. context
* information.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_set_preset_switch_failed_event_callback(projectm_playlist_handle instance,
projectm_playlist_preset_switch_failed_event callback,
void* user_data);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,79 @@
/**
* @file playlist_core.h
* @copyright 2003-2023 projectM Team
* @brief Core functions to instantiate, destroy and connect a projectM playlist.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#include "projectM-4/playlist_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Creates a playlist manager for the given projectM instance
*
* Only one active playlist manager is supported per projectM instance. If multiple playlists use
* the same projectM instance, only the last created playlist manager will receive preset change
* callbacks from the projectM instance.
*
* To switch to another playlist, use the projectm_playlist_connect() method.
*
* @param projectm_instance The projectM instance to connect to. Can be a null pointer to leave the newly
* created playlist instance unconnected.
* @return An opaque pointer to the newly created playlist manager instance. Null if creation failed.
*/
PROJECTM_PLAYLIST_EXPORT projectm_playlist_handle projectm_playlist_create(projectm_handle projectm_instance);
/**
* @brief Destroys a previously created playlist manager.
*
* If the playlist manager is currently connected to a projectM instance, it will be disconnected.
*
* @param instance The playlist manager instance to destroy.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_destroy(projectm_playlist_handle instance);
/**
* @brief Connects the playlist manager to a projectM instance.
*
* Sets or removes the preset switch callbacks and stores the projectM instance handle for use with
* manual preset switches via the playlist API.
*
* When switching between multiple playlist managers, first call this method on the last used
* playlist manager with a null pointer for the projectM instance, then call this method with the
* actual projectM instance on the playlist manager that should be activated. It is also safe to
* call projectm_playlist_connect() with a null projectM handle on all playlist manager instances
* before activating a single one with a valid, non-null projectM handle.
*
* @param instance The playlist manager instance.
* @param projectm_instance The projectM instance to connect to. Can be a null pointer to remove
* an existing binding and clear the projectM preset switch callback.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_connect(projectm_playlist_handle instance, projectm_handle projectm_instance);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,99 @@
/**
* @file playlist_filter.h
* @copyright 2003-2023 projectM Team
* @brief Playlist filter functions.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/playlist_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets a new filter list.
*
* <p>Does not immediately apply the new list to an existing playlist, only newly added files
* will be affected. If you need to filter the existing playlist after calling this method,
* additionally call projectm_playlist_apply_filter() afterwards.</p>
*
* <p>The filter list consists of simple globbing expressions similar to the .gitignore syntax:</p>
*
* <ul>
* <li><strong>?</strong>: Matches any single character except /.</li>
* <li><strong>*</strong>: Matches 0 or more characters except /.</li>
* <li><strong>/</strong>: When used at the begin of a glob, matches if
* pathname has no path separator.</li>
* <li><strong>**&zwj;/</strong>: Matches 0 or more directories.</li>
* <li><strong>/&zwj;**</strong>: When at the end of the glob, matches everything after the /.</li>
* </ul>
*
* <p>In globbing expressions, \\ can be used as path separator instead of /. The backslash can't
* be used to escape globbing patterns, so matching literal * and ? in filenames is not possible.
* This is not a huge issue as Windows doesn't allow those characters in filenames and Milkdrop
* files originate from the Windows world. Character classes like "[0-9]" are also not supported to
* keep the syntax simple.</p>
*
* <p>Each line can be prefixed with either + or - to either include files matching the pattern
* or excluding them. Any other character is not interpreted as a prefix and the filter line is
* matching as an exclude filter. To match a literal + or - at the beginning, add the appropriate
* prefix in front. Empty filters never match anything, even if the filename is empty.</p>
*
* <p>The filter list is checked in order. The first pattern that matches the filename determines
* the filter result (include or exclude). If no pattern matches, the file is included. In the case
* that a default exclude action is required, add a "-/&zwj;**" filter at the end of the list.</p>
*
* @param instance The playlist manager instance.
* @param filter_list An array with filter strings.
* @param count The size of the filter array.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_set_filter(projectm_playlist_handle instance, const char** filter_list,
size_t count);
/**
* @brief Returns the current filter list.
*
* Always call projectm_playlist_free_string_array() on the returned pointer if the data is
* no longer needed.
*
* @param instance The playlist manager instance.
* @param[out] count The size of the filter array.
* @return An array with filter strings.
*/
PROJECTM_PLAYLIST_EXPORT char** projectm_playlist_get_filter(projectm_playlist_handle instance, size_t* count);
/**
* @brief Applies the current filter list to the existing playlist.
*
* Note this function only removes items. Previously filtered items are not added again. If items
* were removed, the playback history is cleared.
*
* @param instance The playlist manager instance.
* @return The number of removed items.
*/
PROJECTM_PLAYLIST_EXPORT size_t projectm_playlist_apply_filter(projectm_playlist_handle instance);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,241 @@
/**
* @file playlist_items.h
* @copyright 2003-2023 projectM Team
* @brief Playlist item management functions.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/playlist_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Returns the number of presets in the current playlist.
* @param instance The playlist manager instance.
* @return The number of presets in the current playlist.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_size(projectm_playlist_handle instance);
/**
* @brief Clears the playlist.
* @param instance The playlist manager instance to clear.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_clear(projectm_playlist_handle instance);
/**
* @brief Returns a list of preset files inside the given range of the current playlist, in order.
*
* This function can be used to return the whole playlist to save it to a file, or just a part of
* it for use in virtual lists. If less elements than given in @a count are available, only the
* remainder of items after the starting index are returned. If the starting index equals or exceeds
* the playlist size, an empty list is returned.
*
* @note Call projectm_playlist_free_string_array() when you're done using the list.
* @note Ideally, don't rely on the value provided as count to iterate over the filenames.
* Instead, look for the terminating null pointer to abort the loop.
* @param instance The playlist manager instance.
* @param start The zero-based starting index of the range to return.
* @param count The maximum number if items to return.
* @return A pointer to a list of char pointers, each containing a single preset. The last entry
* is denoted by a null pointer.
*/
PROJECTM_PLAYLIST_EXPORT char** projectm_playlist_items(projectm_playlist_handle instance, uint32_t start, uint32_t count);
/**
* @brief Returns the name of a preset at the given index in the current playlist.
* @note Call projectm_playlist_free_string() when you're done using the return value.
* @note If you need to retrieve a major part of playlist filenames, use projectm_playlist_items()
* instead.
* @param instance The playlist manager instance.
* @param index The index to retrieve the filename for.
* @return The filename of the requested preset, or NULL if the index was out of bounds or the
* playlist is empty.
*/
PROJECTM_PLAYLIST_EXPORT char* projectm_playlist_item(projectm_playlist_handle instance, uint32_t index);
/**
* @brief Appends presets from the given path to the end of the current playlist.
*
* This method will scan the given path for files with a ".milk" extension and add these to the
* playlist.
*
* Symbolic links are not followed.
*
* @param instance The playlist manager instance.
* @param path A local filesystem path to scan for presets.
* @param recurse_subdirs If true, subdirectories of the given path will also be scanned. If false,
* only the exact path given is searched for presets.
* @param allow_duplicates If true, files found will always be added. If false, only files are
* added that do not already exist in the current playlist.
* @return The number of files added. 0 may indicate issues scanning the path.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_add_path(projectm_playlist_handle instance, const char* path,
bool recurse_subdirs, bool allow_duplicates);
/**
* @brief Inserts presets from the given path to the end of the current playlist.
*
* This method will scan the given path for files with a ".milk" extension and add these to the
* playlist.
*
* Symbolic links are not followed.
*
* @param instance The playlist manager instance.
* @param path A local filesystem path to scan for presets.
* @param index The index to insert the presets at. If it exceeds the playlist size, the presets are
* added at the end of the playlist.
* @param recurse_subdirs If true, subdirectories of the given path will also be scanned. If false,
* only the exact path given is searched for presets.
* @param allow_duplicates If true, files found will always be added. If false, only files are
* added that do not already exist in the current playlist.
* @return The number of files added. 0 may indicate issues scanning the path.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_insert_path(projectm_playlist_handle instance, const char* path,
uint32_t index, bool recurse_subdirs, bool allow_duplicates);
/**
* @brief Adds a single preset to the end of the playlist.
*
* @note The file is not checked for existence or for being readable.
*
* @param instance The playlist manager instance.
* @param filename A local preset filename.
* @param allow_duplicates If true, the preset filename will always be added. If false, the preset
* is only added to the playlist if the exact filename doesn't exist in the
* current playlist.
* @return True if the file was added to the playlist, false if the file was a duplicate and
* allow_duplicates was set to false.
*/
PROJECTM_PLAYLIST_EXPORT bool projectm_playlist_add_preset(projectm_playlist_handle instance, const char* filename,
bool allow_duplicates);
/**
* @brief Adds a single preset to the playlist at the specified position.
*
* To always add a file at the end of the playlist, use projectm_playlist_add_preset() as it is
* performs better.
*
* @note The file is not checked for existence or for being readable.
*
* @param instance The playlist manager instance.
* @param filename A local preset filename.
* @param index The index to insert the preset at. If it exceeds the playlist size, the preset is
* added at the end of the playlist.
* @param allow_duplicates If true, the preset filename will always be added. If false, the preset
* is only added to the playlist if the exact filename doesn't exist in the
* current playlist.
* @return True if the file was added to the playlist, false if the file was a duplicate and
* allow_duplicates was set to false.
*/
PROJECTM_PLAYLIST_EXPORT bool projectm_playlist_insert_preset(projectm_playlist_handle instance, const char* filename,
uint32_t index, bool allow_duplicates);
/**
* @brief Adds a list of presets to the end of the playlist.
*
* @note The files are not checked for existence or for being readable.
*
* @param instance The playlist manager instance.
* @param filenames A list of local preset filenames.
* @param count The number of files in the list.
* @param allow_duplicates If true, the preset filenames will always be added. If false, a preset
* is only added to the playlist if the exact filename doesn't exist in the
* current playlist.
* @return The number of files added to the playlist. Ranges between 0 and count.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_add_presets(projectm_playlist_handle instance, const char** filenames,
uint32_t count, bool allow_duplicates);
/**
* @brief Adds a single preset to the playlist at the specified position.
*
* To always add a file at the end of the playlist, use projectm_playlist_add_preset() as it is
* performs better.
*
* @note The files are not checked for existence or for being readable.
*
* @param instance The playlist manager instance.
* @param filenames A list of local preset filenames.
* @param count The number of files in the list.
* @param index The index to insert the presets at. If it exceeds the playlist size, the presets are
* added at the end of the playlist.
* @param allow_duplicates If true, the preset filenames will always be added. If false, a preset
* is only added to the playlist if the exact filename doesn't exist in the
* current playlist.
* @return The number of files added to the playlist. Ranges between 0 and count.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_insert_presets(projectm_playlist_handle instance, const char** filenames,
uint32_t count, unsigned int index, bool allow_duplicates);
/**
* @brief Removes a single preset from the playlist at the specified position.
*
* @param instance The playlist manager instance.
* @param index The preset index to remove. If it exceeds the playlist size, no preset will be
* removed.
* @return True if the preset was removed from the playlist, false if the index was out of range.
*/
PROJECTM_PLAYLIST_EXPORT bool projectm_playlist_remove_preset(projectm_playlist_handle instance, uint32_t index);
/**
* @brief Removes a number of presets from the playlist from the specified position.
*
* @param instance The playlist manager instance.
* @param index The first preset index to remove. If it exceeds the playlist size, no preset will be
* removed.
* @param count The number of presets to remove from the given index.
* @return The number of presets removed from the playlist.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_remove_presets(projectm_playlist_handle instance, uint32_t index,
uint32_t count);
/**
* @brief Sorts part or the whole playlist according to the given predicate and order.
*
* It is safe to provide values in start_index and count that will exceed the number of items
* in the playlist. Only items that fall into an existing index range are sorted. If start_index
* is equal to or larger than the playlist size, no items are sorted. If start_index is inside the
* playlist, but adding count results in an index outside the playlist, items until the end are
* sorted.
*
* Sort order is lexicographical for both predicates and case-sensitive.
*
* If invalid values are provides as predicate or order, the defaults as mentioned in the parameter
* description are used.
*
* @param instance The playlist manager instance.
* @param start_index The starting index to begin sorting at.
* @param count The number of items, beginning at start_index, to sort.
* @param predicate The predicate to use for sorting. Default is SORT_PREDICATE_FULL_PATH.
* @param order The sort order. Default is SORT_ORDER_ASCENDING.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_sort(projectm_playlist_handle instance, uint32_t start_index, uint32_t count,
projectm_playlist_sort_predicate predicate, projectm_playlist_sort_order order);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,56 @@
/**
* @file playlist_memory.h
* @copyright 2003-2023 projectM Team
* @brief Memory allocation/deallocation helpers.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/playlist_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Frees a char pointer returned by any of the playlist API functions.
*
* Please only use this function with char pointers returned by the playlist library, and don't use
* other projectM memory management functions with pointers returned by the playlist library.
*
* @param string A pointer to a string that should be freed.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_free_string(char* string);
/**
* @brief Frees a string array returned by any of the playlist API functions.
*
* Please only use this function with pointers returned by the playlist library, and don't use
* other projectM memory management functions with pointers returned by the playlist library.
*
* @param array The pointer to the array of strings that should be freed.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_free_string_array(char** array);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,136 @@
/**
* @file playlist_playback.h
* @copyright 2003-2023 projectM Team
* @brief Playback control functions.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/playlist_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable or disable shuffle mode.
* @param instance The playlist manager instance.
* @param shuffle True to enable random shuffling, false to play presets in playlist order.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_set_shuffle(projectm_playlist_handle instance, bool shuffle);
/**
* @brief Retrieves the current state of shuffle mode.
* @param instance The playlist manager instance.
* @return True if shuffle mode is enabled, false otherwise.
*/
PROJECTM_PLAYLIST_EXPORT bool projectm_playlist_get_shuffle(projectm_playlist_handle instance);
/**
* @brief Sets the number of retries after failed preset switches.
* @note Don't set this value too high, as each retry is done recursively.
* @param instance The playlist manager instance.
* @param retry_count The number of retries after failed preset switches. Default is 5. Set to 0
* to simply forward the failure event from projectM.
*/
PROJECTM_PLAYLIST_EXPORT void projectm_playlist_set_retry_count(projectm_playlist_handle instance, uint32_t retry_count);
/**
* @brief Returns the number of retries after failed preset switches.
* @param instance The playlist manager instance.
* @return The number of retries after failed preset switches.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_get_retry_count(projectm_playlist_handle instance);
/**
* @brief Plays the preset at the requested playlist position and returns the actual playlist index.
*
* If the requested position is out of bounds, the returned position will wrap to 0, effectively
* repeating the playlist as if shuffle was disabled. It has no effect if the playlist is empty.
*
* This method ignores the shuffle setting and will always jump to the requested index, given it is
* within playlist bounds.
*
* @param instance The playlist manager instance.
* @param new_position The new position to jump to.
* @param hard_cut If true, the preset transition is instant. If true, a smooth transition is played.
* @return The new playlist position. If the playlist is empty, 0 will be returned.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_set_position(projectm_playlist_handle instance, uint32_t new_position,
bool hard_cut);
/**
* @brief Returns the current playlist position.
* @param instance The playlist manager instance.
* @return The current playlist position. If the playlist is empty, 0 will be returned.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_get_position(projectm_playlist_handle instance);
/**
* @brief Plays the next playlist item and returns the index of the new preset.
*
* If shuffle is on, it will select a random preset, otherwise the next in the playlist. If the
* end of the playlist is reached in continuous mode, it will wrap back to 0.
*
* The old playlist item is added to the history.
*
* @param instance The playlist manager instance.
* @param hard_cut If true, the preset transition is instant. If true, a smooth transition is played.
* @return The new playlist position. If the playlist is empty, 0 will be returned.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_play_next(projectm_playlist_handle instance, bool hard_cut);
/**
* @brief Plays the previous playlist item and returns the index of the new preset.
*
* If shuffle is on, it will select a random preset, otherwise the next in the playlist. If the
* end of the playlist is reached in continuous mode, it will wrap back to 0.
*
* The old playlist item is added to the history.
*
* @param instance The playlist manager instance.
* @param hard_cut If true, the preset transition is instant. If true, a smooth transition is played.
* @return The new playlist position. If the playlist is empty, 0 will be returned.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_play_previous(projectm_playlist_handle instance, bool hard_cut);
/**
* @brief Plays the last preset played in the history and returns the index of the preset.
*
* The history keeps track of the last 1000 presets and will go back in the history. The
* playback history will be cleared whenever the playlist items are changed.
*
* If the history is empty, this call behaves identical to projectm_playlist_play_previous(),
* but the item is not added to the history.
*
* Presets which failed to load are not recorded in the history and thus will be skipped when
* calling this method.
*
* @param instance The playlist manager instance.
* @param hard_cut If true, the preset transition is instant. If true, a smooth transition is played.
* @return The new playlist position. If the playlist is empty, 0 will be returned.
*/
PROJECTM_PLAYLIST_EXPORT uint32_t projectm_playlist_play_last(projectm_playlist_handle instance, bool hard_cut);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,58 @@
/**
* @file playlist_types.h
* @copyright 2003-2023 projectM Team
* @brief Types and enumerations used in the playlist API headers.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/projectM_playlist_export.h"
#ifdef __cplusplus
extern "C" {
#endif
struct projectm_playlist; //!< Opaque projectM playlist instance type.
typedef struct projectm_playlist* projectm_playlist_handle; //!< A pointer to the opaque projectM playlist instance.
/**
* Sort predicate for playlist sorting.
*/
typedef enum
{
SORT_PREDICATE_FULL_PATH, //!< Sort by full path name
SORT_PREDICATE_FILENAME_ONLY //!< Sort only by preset filename
} projectm_playlist_sort_predicate;
/**
* Sort order for playlist sorting.
*/
typedef enum
{
SORT_ORDER_ASCENDING, //!< Sort in alphabetically ascending order.
SORT_ORDER_DESCENDING //!< Sort in alphabetically descending order.
} projectm_playlist_sort_order;
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,35 @@
/**
* @file projectM.h
* @copyright 2003-2023 projectM Team
* @brief Convenience include file that includes all other API headers.
*
* projectM -- Milkdrop-esque visualisation SDK
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/audio.h"
#include "projectM-4/callbacks.h"
#include "projectM-4/core.h"
#include "projectM-4/debug.h"
#include "projectM-4/memory.h"
#include "projectM-4/parameters.h"
#include "projectM-4/render_opengl.h"
#include "projectM-4/touch.h"
#include "projectM-4/version.h"

View file

@ -0,0 +1,42 @@
#ifndef PROJECTM_EXPORT_H
#define PROJECTM_EXPORT_H
#ifdef PROJECTM_STATIC_DEFINE
# define PROJECTM_EXPORT
# define PROJECTM_NO_EXPORT
#else
# ifndef PROJECTM_EXPORT
# ifdef projectM_api_EXPORTS
/* We are building this library */
# define PROJECTM_EXPORT __attribute__((visibility("default")))
# else
/* We are using this library */
# define PROJECTM_EXPORT __attribute__((visibility("default")))
# endif
# endif
# ifndef PROJECTM_NO_EXPORT
# define PROJECTM_NO_EXPORT __attribute__((visibility("hidden")))
# endif
#endif
#ifndef PROJECTM_DEPRECATED
# define PROJECTM_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef PROJECTM_DEPRECATED_EXPORT
# define PROJECTM_DEPRECATED_EXPORT PROJECTM_EXPORT PROJECTM_DEPRECATED
#endif
#ifndef PROJECTM_DEPRECATED_NO_EXPORT
# define PROJECTM_DEPRECATED_NO_EXPORT PROJECTM_NO_EXPORT PROJECTM_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef PROJECTM_NO_DEPRECATED
# define PROJECTM_NO_DEPRECATED
# endif
#endif
#endif /* PROJECTM_EXPORT_H */

View file

@ -0,0 +1,42 @@
#ifndef PROJECTM_PLAYLIST_EXPORT_H
#define PROJECTM_PLAYLIST_EXPORT_H
#ifdef PROJECTM_PLAYLIST_STATIC_DEFINE
# define PROJECTM_PLAYLIST_EXPORT
# define PROJECTM_PLAYLIST_NO_EXPORT
#else
# ifndef PROJECTM_PLAYLIST_EXPORT
# ifdef projectM_playlist_EXPORTS
/* We are building this library */
# define PROJECTM_PLAYLIST_EXPORT __attribute__((visibility("default")))
# else
/* We are using this library */
# define PROJECTM_PLAYLIST_EXPORT __attribute__((visibility("default")))
# endif
# endif
# ifndef PROJECTM_PLAYLIST_NO_EXPORT
# define PROJECTM_PLAYLIST_NO_EXPORT __attribute__((visibility("hidden")))
# endif
#endif
#ifndef PROJECTM_PLAYLIST_DEPRECATED
# define PROJECTM_PLAYLIST_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef PROJECTM_PLAYLIST_DEPRECATED_EXPORT
# define PROJECTM_PLAYLIST_DEPRECATED_EXPORT PROJECTM_PLAYLIST_EXPORT PROJECTM_PLAYLIST_DEPRECATED
#endif
#ifndef PROJECTM_PLAYLIST_DEPRECATED_NO_EXPORT
# define PROJECTM_PLAYLIST_DEPRECATED_NO_EXPORT PROJECTM_PLAYLIST_NO_EXPORT PROJECTM_PLAYLIST_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef PROJECTM_PLAYLIST_NO_DEPRECATED
# define PROJECTM_PLAYLIST_NO_DEPRECATED
# endif
#endif
#endif /* PROJECTM_PLAYLIST_EXPORT_H */

View file

@ -0,0 +1,46 @@
/**
* @file render_opengl.h
* @copyright 2003-2023 projectM Team
* @brief Functions to configure and render projectM visuals using OpenGL.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Renders a single frame.
*
* @note Separate two-pass frame rendering is currently not supported by the C API as it is rarely used
* and also depends on the loaded preset.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_opengl_render_frame(projectm_handle instance);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,78 @@
/**
* @file touch.h
* @copyright 2003-2023 projectM Team
* @brief Touch-related functions to add random waveforms.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Starts a touch event or moves an existing waveform.
*
* This will add or move waveforms in addition to the preset waveforms. If there is an existing waveform
* at the given coordinates, it will be centered on the new coordinates. If there is no waveform, a new one
* will be added.
*
* @param instance The projectM instance handle.
* @param x The x coordinate of the touch event.
* @param y The y coordinate of the touch event.
* @param pressure The amount of pressure applied in a range from 0.0 to 1.0.
* @param touch_type The waveform type that will be rendered on touch.
*/
PROJECTM_EXPORT void projectm_touch(projectm_handle instance, float x, float y,
int pressure, projectm_touch_type touch_type);
/**
* @brief Centers any waveforms under the coordinates to simulate dragging.
* @param instance The projectM instance handle.
* @param x The x coordinate of the drag.
* @param y the y coordinate of the drag.
* @param pressure The amount of pressure applied in a range from 0.0 to 1.0.
*/
PROJECTM_EXPORT void projectm_touch_drag(projectm_handle instance, float x, float y, int pressure);
/**
* @brief Removes any additional touch waveforms under the given coordinates.
* @param instance The projectM instance handle.
* @param x The last known x touch coordinate.
* @param y The last known y touch coordinate.
*/
PROJECTM_EXPORT void projectm_touch_destroy(projectm_handle instance, float x, float y);
/**
* @brief Removes all touch waveforms from the screen.
*
* Preset-defined waveforms will still be displayed.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_touch_destroy_all(projectm_handle instance);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,80 @@
/**
* @file types.h
* @copyright 2003-2023 projectM Team
* @brief Types and enumerations used in the other API headers.
*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2023 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM-4/projectM_export.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
struct projectm; //!< Opaque projectM instance type.
typedef struct projectm* projectm_handle; //!< A pointer to the opaque projectM instance.
/**
* For specifying audio data format.
*/
typedef enum
{
PROJECTM_MONO = 1,
PROJECTM_STEREO = 2
} projectm_channels;
/**
* Placeholder values that can be used to address channel indices in PCM data arrays.
*/
typedef enum
{
PROJECTM_CHANNEL_L = 0, //!< Left audio channel.
PROJECTM_CHANNEL_0 = 0, //!< Left audio channel.
PROJECTM_CHANNEL_R = 1, //!< Right audio channel.
PROJECTM_CHANNEL_1 = 1 //!< Right audio channel.
} projectm_pcm_channel;
/**
* Waveform render types used in the touch start method.
*/
typedef enum
{
PROJECTM_TOUCH_TYPE_RANDOM, //!< Random waveform type.
PROJECTM_TOUCH_TYPE_CIRCLE, //!< Draws a circular waveform.
PROJECTM_TOUCH_TYPE_RADIAL_BLOB, //!< Draws a radial blob waveform.
PROJECTM_TOUCH_TYPE_BLOB2, //!< Draws a blob-style waveform.
PROJECTM_TOUCH_TYPE_BLOB3, //!< Draws another blob-style waveform.
PROJECTM_TOUCH_TYPE_DERIVATIVE_LINE, //!< Draws a derivative-line waveform.
PROJECTM_TOUCH_TYPE_BLOB5, //!< Draws a five-blob waveform.
PROJECTM_TOUCH_TYPE_LINE, //!< Draws a single-line waveform.
PROJECTM_TOUCH_TYPE_DOUBLE_LINE //!< Draws a double-line waveform.
} projectm_touch_type;
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,11 @@
#pragma once
#define PROJECTM_VERSION_MAJOR 4
#define PROJECTM_VERSION_MINOR 1
#define PROJECTM_VERSION_PATCH 4
/* Full version number as a string literal */
#define PROJECTM_VERSION_STRING "4.1.4"
/* VCS version number, e.g. Git commit hash */
#define PROJECTM_VERSION_VCS "Unknown"

@ -0,0 +1 @@
Subproject commit ff8edf2a8fa07e55ad562f1af97076526c484f7d

@ -0,0 +1 @@
Subproject commit 4e0bf9f0ca92dcdf00b049701e20ef57b1d2c406

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,25 @@
//
// ProjectMView.h
// Cog
//
// Created by Christopher Snowhill on 3/11/25.
//
#ifndef ProjectMView_h
#define ProjectMView_h
#import <Cocoa/Cocoa.h>
#import <CogAudio/VisualizationController.h>
NS_ASSUME_NONNULL_BEGIN
@interface ProjectMView : NSOpenGLView
-(id)initWithFrame:(NSRect)frame;
@end
NS_ASSUME_NONNULL_END
#endif /* ProjectMView_h */

View file

@ -0,0 +1,174 @@
//
// SpectrumViewPM.m
// Cog
//
// Created by Christopher Snowhill on 3/11/25.
//
#import "ProjectMView.h"
#import "NSView+Visibility.h"
#include <OpenGL/gl3.h>
#import <projectM-4/projectM.h>
#import <projectM-4/playlist.h>
#import "Logging.h"
static void *kProjectMViewContext = &kProjectMViewContext;
extern NSString *CogPlaybackDidBeginNotificiation;
extern NSString *CogPlaybackDidPauseNotificiation;
extern NSString *CogPlaybackDidResumeNotificiation;
extern NSString *CogPlaybackDidStopNotificiation;
@implementation ProjectMView {
VisualizationController *visController;
projectm_handle pm;
projectm_playlist_handle pl;
float visAudio[4096];
NSTimer *timer;
}
- (id)initWithFrame:(NSRect)frame {
NSOpenGLPixelFormatAttribute attr[] = {
NSOpenGLPFAAllowOfflineRenderers,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
kCGLPFASupportsAutomaticGraphicsSwitching,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAClosestPolicy,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
0
};
NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
if(!fmt) {
return nil;
}
self = [super initWithFrame:frame pixelFormat:fmt];
if(self) {
self.wantsBestResolutionOpenGLSurface = YES;
visController = [NSClassFromString(@"VisualizationController") sharedController];
timer = [NSTimer timerWithTimeInterval:(1.0 / 60.0) repeats:YES block:^(NSTimer * _Nonnull timer) {
self.needsDisplay = YES;
}];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
return self;
}
- (void)dealloc {
[timer invalidate];
timer = nil;
if(pl) {
projectm_playlist_destroy(pl);
}
if(pm) {
projectm_destroy(pm);
}
}
static void presetFailed(const char *preset_filename, const char *message, void *user_data) {
NSLog(@"ProjectM preset failed: %s - for reason: %s", preset_filename, message);
}
- (void)initProjectM {
if(!pm && !pl) {
NSBundle* me = [NSBundle bundleForClass: self.class];
NSLog(@"main bundle: %@", [me bundlePath]);
NSString* presetsPath = [me pathForResource:@"presets" ofType:nil];
NSLog(@"presets path %@", presetsPath);
NSString* texturesPath = [me pathForResource:@"textures" ofType:nil];
NSLog(@"textures path %@", texturesPath);
pm = projectm_create();
if(!pm) {
return;
}
char *_texturesPath = projectm_alloc_string((int)(strlen([texturesPath UTF8String]) + 1));
if(!_texturesPath) {
return;
}
strcpy(_texturesPath, [texturesPath UTF8String]);
const char *texturesPaths[1] = { _texturesPath };
projectm_set_texture_search_paths(pm, texturesPaths, 1);
projectm_free_string(_texturesPath);
NSRect rect = [self.window convertRectToBacking:self.bounds];
projectm_set_window_size(pm, rect.size.width, rect.size.height);
projectm_set_fps(pm, 60);
projectm_set_mesh_size(pm, 48, 32);
projectm_set_aspect_correction(pm, true);
projectm_set_preset_locked(pm, false);
projectm_set_preset_duration(pm, 30.0);
projectm_set_soft_cut_duration(pm, 3.0);
projectm_set_hard_cut_enabled(pm, false);
projectm_set_hard_cut_duration(pm, 20.0);
projectm_set_hard_cut_sensitivity(pm, 1.0);
projectm_set_beat_sensitivity(pm, 1.0);
pl = projectm_playlist_create(pm);
if(!pl) {
return;
}
projectm_playlist_set_preset_switch_failed_event_callback(pl, presetFailed, NULL);
char *_presetsPath = projectm_alloc_string((int)(strlen([presetsPath UTF8String]) + 1));
if(!_presetsPath) {
return;
}
strcpy(_presetsPath, [presetsPath UTF8String]);
projectm_playlist_add_path(pl, _presetsPath, true, false);
projectm_free_string(_presetsPath);
projectm_playlist_sort(pl, 0, projectm_playlist_size(pl), SORT_PREDICATE_FILENAME_ONLY, SORT_ORDER_ASCENDING);
projectm_playlist_set_shuffle(pl, true);
}
}
- (void)drawRect:(NSRect)dirtyRect {
[[self openGLContext] makeCurrentContext];
[self initProjectM];
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
NSRect rect = [self.window convertRectToBacking:self.bounds];
projectm_set_window_size(pm, rect.size.width, rect.size.height);
[self->visController copyVisPCM:&visAudio[0] visFFT:nil latencyOffset:0];
size_t maxSamples = projectm_pcm_get_max_samples();
if(maxSamples > 4096) maxSamples = 4096;
projectm_pcm_add_float(pm, &visAudio[0], (unsigned int)maxSamples, 1);
projectm_opengl_render_frame(pm);
[[self openGLContext] flushBuffer];
[NSOpenGLContext clearCurrentContext];
}
@end

View file

@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SpectrumViewCG : NSView @interface SpectrumViewCG : NSView
@property(nonatomic) BOOL isListening; @property(nonatomic) BOOL isListening;
- (id)initWithFrame:(NSRect)frame;
- (void)startPlayback; - (void)startPlayback;
- (void)enableFullView; - (void)enableFullView;
@end @end

View file

@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (SpectrumViewSK *)createGuardWithFrame:(NSRect)frame; + (SpectrumViewSK *)createGuardWithFrame:(NSRect)frame;
- (id)initWithFrame:(NSRect)frame;
- (void)enableCameraControl; - (void)enableCameraControl;
- (void)startPlayback; - (void)startPlayback;
@end @end

View file

@ -9,12 +9,14 @@
#import "SpectrumViewSK.h" #import "SpectrumViewSK.h"
#import "SpectrumViewCG.h" #import "SpectrumViewCG.h"
#import "ProjectMView.h"
static void *kSpectrumWindowContext = &kSpectrumWindowContext; static void *kSpectrumWindowContext = &kSpectrumWindowContext;
@interface SpectrumWindowController () @interface SpectrumWindowController ()
@property SpectrumViewSK *spectrumViewSK; @property SpectrumViewSK *spectrumViewSK;
@property SpectrumViewCG *spectrumViewCG; @property SpectrumViewCG *spectrumViewCG;
@property ProjectMView *projectMView;
@end @end
@implementation SpectrumWindowController @implementation SpectrumWindowController
@ -29,8 +31,6 @@ static void *kSpectrumWindowContext = &kSpectrumWindowContext;
- (void)windowDidLoad { - (void)windowDidLoad {
[super windowDidLoad]; [super windowDidLoad];
[self startRunning];
} }
- (void)dealloc { - (void)dealloc {
@ -53,6 +53,14 @@ static void *kSpectrumWindowContext = &kSpectrumWindowContext;
} }
- (void)startRunning { - (void)startRunning {
if(!self.projectMView) {
NSRect frame = [[self window] frame];
self.projectMView = [[ProjectMView alloc] initWithFrame:frame];
if(self.projectMView) {
[[self window] setContentView:self.projectMView];
}
}
#if 0
if(!self.spectrumViewSK && !self.spectrumViewCG) { if(!self.spectrumViewSK && !self.spectrumViewCG) {
NSRect frame = [[self window] frame]; NSRect frame = [[self window] frame];
self.spectrumViewSK = [SpectrumViewSK createGuardWithFrame:frame]; self.spectrumViewSK = [SpectrumViewSK createGuardWithFrame:frame];
@ -76,12 +84,14 @@ static void *kSpectrumWindowContext = &kSpectrumWindowContext;
else if(self.spectrumViewCG) else if(self.spectrumViewCG)
[self.spectrumViewCG startPlayback]; [self.spectrumViewCG startPlayback];
} }
#endif
} }
- (void)stopRunning { - (void)stopRunning {
[[self window] setContentView:nil]; [[self window] setContentView:nil];
self.spectrumViewSK = nil; self.spectrumViewSK = nil;
self.spectrumViewCG = nil; self.spectrumViewCG = nil;
self.projectMView = nil;
} }
- (void)windowWillClose:(NSNotification *)notification { - (void)windowWillClose:(NSNotification *)notification {