[Audio Output] Resample unsupported sample rates
These rates are too high for Apple's output routines, for some reason. Signed-off-by: Christopher Snowhill <kode54@gmail.com>lastfm
parent
6d772562ca
commit
2e45deb8d3
|
@ -19,3 +19,6 @@
|
||||||
[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 "Audio/ThirdParty/r8brain-free-src"]
|
||||||
|
path = Audio/ThirdParty/r8brain-free-src
|
||||||
|
url = https://github.com/kode54/r8brain-free-src
|
||||||
|
|
|
@ -452,10 +452,12 @@
|
||||||
|
|
||||||
[self notifyPlaybackStopped:nil];
|
[self notifyPlaybackStopped:nil];
|
||||||
|
|
||||||
return NO;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
[output setEndOfStream:NO];
|
||||||
|
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)endOfInputPlayed {
|
- (void)endOfInputPlayed {
|
||||||
|
@ -465,7 +467,6 @@
|
||||||
// - the buffer chain for the next entry is the first item in chainQueue
|
// - the buffer chain for the next entry is the first item in chainQueue
|
||||||
|
|
||||||
[self notifyStreamChanged:[bufferChain userInfo]];
|
[self notifyStreamChanged:[bufferChain userInfo]];
|
||||||
[output setEndOfStream:NO];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)chainQueueHasTracks {
|
- (BOOL)chainQueueHasTracks {
|
||||||
|
|
|
@ -41,6 +41,35 @@
|
||||||
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DD30B8D0F7000A34E87 /* PluginController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DD30B8D0F7000A34E87 /* PluginController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
17F94DD60B8D0F7000A34E87 /* PluginController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.mm */; };
|
17F94DD60B8D0F7000A34E87 /* PluginController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.mm */; };
|
||||||
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
831A4FDC2865A7DC0049CFE4 /* CDSPProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4F9D2865A7DC0049CFE4 /* CDSPProcessor.h */; };
|
||||||
|
831A4FDD2865A7DC0049CFE4 /* CDSPRealFFT.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4F9E2865A7DC0049CFE4 /* CDSPRealFFT.h */; };
|
||||||
|
831A4FDE2865A7DC0049CFE4 /* pffft_double.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA02865A7DC0049CFE4 /* pffft_double.h */; };
|
||||||
|
831A4FDF2865A7DC0049CFE4 /* pf_neon_double_from_avx.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA22865A7DC0049CFE4 /* pf_neon_double_from_avx.h */; };
|
||||||
|
831A4FE02865A7DC0049CFE4 /* pf_double.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA32865A7DC0049CFE4 /* pf_double.h */; };
|
||||||
|
831A4FE12865A7DC0049CFE4 /* pf_neon_double.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA42865A7DC0049CFE4 /* pf_neon_double.h */; };
|
||||||
|
831A4FE22865A7DC0049CFE4 /* pf_sse2_double.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA52865A7DC0049CFE4 /* pf_sse2_double.h */; };
|
||||||
|
831A4FE32865A7DC0049CFE4 /* pf_avx_double.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA62865A7DC0049CFE4 /* pf_avx_double.h */; };
|
||||||
|
831A4FE42865A7DC0049CFE4 /* pf_scalar_double.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA72865A7DC0049CFE4 /* pf_scalar_double.h */; };
|
||||||
|
831A4FE52865A7DC0049CFE4 /* pffft_priv_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FA82865A7DC0049CFE4 /* pffft_priv_impl.h */; };
|
||||||
|
831A4FE62865A7DC0049CFE4 /* pffft_double.c in Sources */ = {isa = PBXBuildFile; fileRef = 831A4FA92865A7DC0049CFE4 /* pffft_double.c */; };
|
||||||
|
831A4FF22865A7DC0049CFE4 /* CDSPHBUpsampler.inc in Sources */ = {isa = PBXBuildFile; fileRef = 831A4FB72865A7DC0049CFE4 /* CDSPHBUpsampler.inc */; };
|
||||||
|
831A4FF32865A7DC0049CFE4 /* r8butil.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FB82865A7DC0049CFE4 /* r8butil.h */; };
|
||||||
|
831A4FF52865A7DC0049CFE4 /* r8bbase.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FBA2865A7DC0049CFE4 /* r8bbase.h */; };
|
||||||
|
831A4FFE2865A7DC0049CFE4 /* CDSPSincFilterGen.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FC42865A7DC0049CFE4 /* CDSPSincFilterGen.h */; };
|
||||||
|
831A50072865A7DC0049CFE4 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 831A4FD02865A7DC0049CFE4 /* LICENSE */; };
|
||||||
|
831A50082865A7DC0049CFE4 /* CDSPResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD12865A7DC0049CFE4 /* CDSPResampler.h */; };
|
||||||
|
831A50092865A7DC0049CFE4 /* CDSPHBUpsampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD22865A7DC0049CFE4 /* CDSPHBUpsampler.h */; };
|
||||||
|
831A500B2865A7DC0049CFE4 /* CDSPBlockConvolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD42865A7DC0049CFE4 /* CDSPBlockConvolver.h */; };
|
||||||
|
831A500C2865A7DC0049CFE4 /* fft4g.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD52865A7DC0049CFE4 /* fft4g.h */; };
|
||||||
|
831A500D2865A7DC0049CFE4 /* CDSPHBDownsampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD62865A7DC0049CFE4 /* CDSPHBDownsampler.h */; };
|
||||||
|
831A500E2865A7DC0049CFE4 /* r8bconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD72865A7DC0049CFE4 /* r8bconf.h */; };
|
||||||
|
831A500F2865A7DC0049CFE4 /* CDSPFracInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD82865A7DC0049CFE4 /* CDSPFracInterpolator.h */; };
|
||||||
|
831A50102865A7DC0049CFE4 /* CDSPFIRFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FD92865A7DC0049CFE4 /* CDSPFIRFilter.h */; };
|
||||||
|
831A50112865A7DC0049CFE4 /* r8bbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831A4FDA2865A7DC0049CFE4 /* r8bbase.cpp */; };
|
||||||
|
831A50122865A7DC0049CFE4 /* pffft.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A4FDB2865A7DC0049CFE4 /* pffft.h */; };
|
||||||
|
831A50142865A7FD0049CFE4 /* r8bstate.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 831A50132865A7FD0049CFE4 /* r8bstate.hpp */; };
|
||||||
|
831A50162865A8800049CFE4 /* r8bstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831A50152865A8800049CFE4 /* r8bstate.cpp */; };
|
||||||
|
831A50182865A8B30049CFE4 /* r8bstate.h in Headers */ = {isa = PBXBuildFile; fileRef = 831A50172865A8B30049CFE4 /* r8bstate.h */; };
|
||||||
8328995327CB511000D7F028 /* RedundantPlaylistDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */; };
|
8328995327CB511000D7F028 /* RedundantPlaylistDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */; };
|
||||||
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */; };
|
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */; };
|
||||||
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995527CB51B700D7F028 /* SHA256Digest.h */; };
|
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995527CB51B700D7F028 /* SHA256Digest.h */; };
|
||||||
|
@ -140,6 +169,35 @@
|
||||||
17F94DD40B8D0F7000A34E87 /* PluginController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginController.mm; sourceTree = "<group>"; };
|
17F94DD40B8D0F7000A34E87 /* PluginController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginController.mm; sourceTree = "<group>"; };
|
||||||
17F94DDC0B8D101100A34E87 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
|
17F94DDC0B8D101100A34E87 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
|
||||||
32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; };
|
32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; };
|
||||||
|
831A4F9D2865A7DC0049CFE4 /* CDSPProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPProcessor.h; sourceTree = "<group>"; };
|
||||||
|
831A4F9E2865A7DC0049CFE4 /* CDSPRealFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPRealFFT.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA02865A7DC0049CFE4 /* pffft_double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pffft_double.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA22865A7DC0049CFE4 /* pf_neon_double_from_avx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pf_neon_double_from_avx.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA32865A7DC0049CFE4 /* pf_double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pf_double.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA42865A7DC0049CFE4 /* pf_neon_double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pf_neon_double.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA52865A7DC0049CFE4 /* pf_sse2_double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pf_sse2_double.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA62865A7DC0049CFE4 /* pf_avx_double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pf_avx_double.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA72865A7DC0049CFE4 /* pf_scalar_double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pf_scalar_double.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA82865A7DC0049CFE4 /* pffft_priv_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pffft_priv_impl.h; sourceTree = "<group>"; };
|
||||||
|
831A4FA92865A7DC0049CFE4 /* pffft_double.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pffft_double.c; sourceTree = "<group>"; };
|
||||||
|
831A4FB72865A7DC0049CFE4 /* CDSPHBUpsampler.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = CDSPHBUpsampler.inc; sourceTree = "<group>"; };
|
||||||
|
831A4FB82865A7DC0049CFE4 /* r8butil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = r8butil.h; sourceTree = "<group>"; };
|
||||||
|
831A4FBA2865A7DC0049CFE4 /* r8bbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = r8bbase.h; sourceTree = "<group>"; };
|
||||||
|
831A4FC42865A7DC0049CFE4 /* CDSPSincFilterGen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPSincFilterGen.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD02865A7DC0049CFE4 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
|
||||||
|
831A4FD12865A7DC0049CFE4 /* CDSPResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPResampler.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD22865A7DC0049CFE4 /* CDSPHBUpsampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPHBUpsampler.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD42865A7DC0049CFE4 /* CDSPBlockConvolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPBlockConvolver.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD52865A7DC0049CFE4 /* fft4g.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fft4g.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD62865A7DC0049CFE4 /* CDSPHBDownsampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPHBDownsampler.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD72865A7DC0049CFE4 /* r8bconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = r8bconf.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD82865A7DC0049CFE4 /* CDSPFracInterpolator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPFracInterpolator.h; sourceTree = "<group>"; };
|
||||||
|
831A4FD92865A7DC0049CFE4 /* CDSPFIRFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDSPFIRFilter.h; sourceTree = "<group>"; };
|
||||||
|
831A4FDA2865A7DC0049CFE4 /* r8bbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = r8bbase.cpp; sourceTree = "<group>"; };
|
||||||
|
831A4FDB2865A7DC0049CFE4 /* pffft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pffft.h; sourceTree = "<group>"; };
|
||||||
|
831A50132865A7FD0049CFE4 /* r8bstate.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = r8bstate.hpp; sourceTree = "<group>"; };
|
||||||
|
831A50152865A8800049CFE4 /* r8bstate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = r8bstate.cpp; sourceTree = "<group>"; };
|
||||||
|
831A50172865A8B30049CFE4 /* r8bstate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = r8bstate.h; sourceTree = "<group>"; };
|
||||||
8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RedundantPlaylistDataStore.m; path = ../../Utils/RedundantPlaylistDataStore.m; sourceTree = "<group>"; };
|
8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RedundantPlaylistDataStore.m; path = ../../Utils/RedundantPlaylistDataStore.m; sourceTree = "<group>"; };
|
||||||
8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RedundantPlaylistDataStore.h; path = ../../Utils/RedundantPlaylistDataStore.h; sourceTree = "<group>"; };
|
8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RedundantPlaylistDataStore.h; path = ../../Utils/RedundantPlaylistDataStore.h; sourceTree = "<group>"; };
|
||||||
8328995527CB51B700D7F028 /* SHA256Digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHA256Digest.h; path = ../../Utils/SHA256Digest.h; sourceTree = "<group>"; };
|
8328995527CB51B700D7F028 /* SHA256Digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHA256Digest.h; path = ../../Utils/SHA256Digest.h; sourceTree = "<group>"; };
|
||||||
|
@ -332,6 +390,10 @@
|
||||||
17D21CD80B8BE5B400D1EBDE /* ThirdParty */ = {
|
17D21CD80B8BE5B400D1EBDE /* ThirdParty */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
831A50152865A8800049CFE4 /* r8bstate.cpp */,
|
||||||
|
831A50172865A8B30049CFE4 /* r8bstate.h */,
|
||||||
|
831A50132865A7FD0049CFE4 /* r8bstate.hpp */,
|
||||||
|
831A4F9C2865A7DC0049CFE4 /* r8brain-free-src */,
|
||||||
8377C64A27B8C51500E8BC0F /* deadbeef */,
|
8377C64A27B8C51500E8BC0F /* deadbeef */,
|
||||||
835C88AE279811A500E28EAE /* hdcd */,
|
835C88AE279811A500E28EAE /* hdcd */,
|
||||||
17D21DC40B8BE79700D1EBDE /* CoreAudioUtils */,
|
17D21DC40B8BE79700D1EBDE /* CoreAudioUtils */,
|
||||||
|
@ -377,6 +439,55 @@
|
||||||
name = "Other Sources";
|
name = "Other Sources";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
831A4F9C2865A7DC0049CFE4 /* r8brain-free-src */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
831A4F9D2865A7DC0049CFE4 /* CDSPProcessor.h */,
|
||||||
|
831A4F9E2865A7DC0049CFE4 /* CDSPRealFFT.h */,
|
||||||
|
831A4F9F2865A7DC0049CFE4 /* pffft_double */,
|
||||||
|
831A4FB72865A7DC0049CFE4 /* CDSPHBUpsampler.inc */,
|
||||||
|
831A4FB82865A7DC0049CFE4 /* r8butil.h */,
|
||||||
|
831A4FBA2865A7DC0049CFE4 /* r8bbase.h */,
|
||||||
|
831A4FC42865A7DC0049CFE4 /* CDSPSincFilterGen.h */,
|
||||||
|
831A4FD02865A7DC0049CFE4 /* LICENSE */,
|
||||||
|
831A4FD12865A7DC0049CFE4 /* CDSPResampler.h */,
|
||||||
|
831A4FD22865A7DC0049CFE4 /* CDSPHBUpsampler.h */,
|
||||||
|
831A4FD42865A7DC0049CFE4 /* CDSPBlockConvolver.h */,
|
||||||
|
831A4FD52865A7DC0049CFE4 /* fft4g.h */,
|
||||||
|
831A4FD62865A7DC0049CFE4 /* CDSPHBDownsampler.h */,
|
||||||
|
831A4FD72865A7DC0049CFE4 /* r8bconf.h */,
|
||||||
|
831A4FD82865A7DC0049CFE4 /* CDSPFracInterpolator.h */,
|
||||||
|
831A4FD92865A7DC0049CFE4 /* CDSPFIRFilter.h */,
|
||||||
|
831A4FDA2865A7DC0049CFE4 /* r8bbase.cpp */,
|
||||||
|
831A4FDB2865A7DC0049CFE4 /* pffft.h */,
|
||||||
|
);
|
||||||
|
path = "r8brain-free-src";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
831A4F9F2865A7DC0049CFE4 /* pffft_double */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
831A4FA02865A7DC0049CFE4 /* pffft_double.h */,
|
||||||
|
831A4FA12865A7DC0049CFE4 /* simd */,
|
||||||
|
831A4FA82865A7DC0049CFE4 /* pffft_priv_impl.h */,
|
||||||
|
831A4FA92865A7DC0049CFE4 /* pffft_double.c */,
|
||||||
|
);
|
||||||
|
path = pffft_double;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
831A4FA12865A7DC0049CFE4 /* simd */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
831A4FA22865A7DC0049CFE4 /* pf_neon_double_from_avx.h */,
|
||||||
|
831A4FA32865A7DC0049CFE4 /* pf_double.h */,
|
||||||
|
831A4FA42865A7DC0049CFE4 /* pf_neon_double.h */,
|
||||||
|
831A4FA52865A7DC0049CFE4 /* pf_sse2_double.h */,
|
||||||
|
831A4FA62865A7DC0049CFE4 /* pf_avx_double.h */,
|
||||||
|
831A4FA72865A7DC0049CFE4 /* pf_scalar_double.h */,
|
||||||
|
);
|
||||||
|
path = simd;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
835C88AE279811A500E28EAE /* hdcd */ = {
|
835C88AE279811A500E28EAE /* hdcd */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -421,30 +532,54 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
17D21CA10B8BE4BA00D1EBDE /* BufferChain.h in Headers */,
|
17D21CA10B8BE4BA00D1EBDE /* BufferChain.h in Headers */,
|
||||||
|
831A4FE02865A7DC0049CFE4 /* pf_double.h in Headers */,
|
||||||
|
831A50142865A7FD0049CFE4 /* r8bstate.hpp in Headers */,
|
||||||
17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */,
|
17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */,
|
||||||
17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */,
|
17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */,
|
||||||
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */,
|
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */,
|
||||||
|
831A4FF32865A7DC0049CFE4 /* r8butil.h in Headers */,
|
||||||
17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */,
|
17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */,
|
||||||
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */,
|
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */,
|
||||||
|
831A50102865A7DC0049CFE4 /* CDSPFIRFilter.h in Headers */,
|
||||||
|
831A4FFE2865A7DC0049CFE4 /* CDSPSincFilterGen.h in Headers */,
|
||||||
|
831A4FF52865A7DC0049CFE4 /* r8bbase.h in Headers */,
|
||||||
|
831A50082865A7DC0049CFE4 /* CDSPResampler.h in Headers */,
|
||||||
17D21CC50B8BE4BA00D1EBDE /* OutputAVFoundation.h in Headers */,
|
17D21CC50B8BE4BA00D1EBDE /* OutputAVFoundation.h in Headers */,
|
||||||
83504165286447DA006B32CC /* Downmix.h in Headers */,
|
83504165286447DA006B32CC /* Downmix.h in Headers */,
|
||||||
|
831A4FDE2865A7DC0049CFE4 /* pffft_double.h in Headers */,
|
||||||
|
831A4FE12865A7DC0049CFE4 /* pf_neon_double.h in Headers */,
|
||||||
17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */,
|
17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */,
|
||||||
17D21CF30B8BE5EF00D1EBDE /* Semaphore.h in Headers */,
|
17D21CF30B8BE5EF00D1EBDE /* Semaphore.h in Headers */,
|
||||||
17D21DC70B8BE79700D1EBDE /* CoreAudioUtils.h in Headers */,
|
17D21DC70B8BE79700D1EBDE /* CoreAudioUtils.h in Headers */,
|
||||||
17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */,
|
17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */,
|
||||||
|
831A50182865A8B30049CFE4 /* r8bstate.h in Headers */,
|
||||||
|
831A4FE52865A7DC0049CFE4 /* pffft_priv_impl.h in Headers */,
|
||||||
|
831A4FE42865A7DC0049CFE4 /* pf_scalar_double.h in Headers */,
|
||||||
|
831A500D2865A7DC0049CFE4 /* CDSPHBDownsampler.h in Headers */,
|
||||||
|
831A500C2865A7DC0049CFE4 /* fft4g.h in Headers */,
|
||||||
8377C65227B8CAD100E8BC0F /* VisualizationController.h in Headers */,
|
8377C65227B8CAD100E8BC0F /* VisualizationController.h in Headers */,
|
||||||
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */,
|
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */,
|
||||||
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */,
|
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */,
|
||||||
|
831A50122865A7DC0049CFE4 /* pffft.h in Headers */,
|
||||||
|
831A4FDC2865A7DC0049CFE4 /* CDSPProcessor.h in Headers */,
|
||||||
|
831A4FDD2865A7DC0049CFE4 /* CDSPRealFFT.h in Headers */,
|
||||||
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */,
|
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */,
|
||||||
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */,
|
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */,
|
||||||
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */,
|
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */,
|
||||||
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
|
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
|
||||||
|
831A50092865A7DC0049CFE4 /* CDSPHBUpsampler.h in Headers */,
|
||||||
|
831A500E2865A7DC0049CFE4 /* r8bconf.h in Headers */,
|
||||||
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */,
|
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */,
|
||||||
17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */,
|
17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */,
|
||||||
|
831A500F2865A7DC0049CFE4 /* CDSPFracInterpolator.h in Headers */,
|
||||||
|
831A4FE22865A7DC0049CFE4 /* pf_sse2_double.h in Headers */,
|
||||||
839065F32853338700636FBB /* dsd2float.h in Headers */,
|
839065F32853338700636FBB /* dsd2float.h in Headers */,
|
||||||
17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */,
|
17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */,
|
||||||
|
831A4FDF2865A7DC0049CFE4 /* pf_neon_double_from_avx.h in Headers */,
|
||||||
|
831A4FE32865A7DC0049CFE4 /* pf_avx_double.h in Headers */,
|
||||||
839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
|
839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
|
||||||
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
|
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
|
||||||
|
831A500B2865A7DC0049CFE4 /* CDSPBlockConvolver.h in Headers */,
|
||||||
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */,
|
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */,
|
||||||
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
|
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
|
||||||
8384912718080FF100E7332D /* Logging.h in Headers */,
|
8384912718080FF100E7332D /* Logging.h in Headers */,
|
||||||
|
@ -516,6 +651,7 @@
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
831A50072865A7DC0049CFE4 /* LICENSE in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -528,8 +664,10 @@
|
||||||
files = (
|
files = (
|
||||||
17D21CA20B8BE4BA00D1EBDE /* BufferChain.m in Sources */,
|
17D21CA20B8BE4BA00D1EBDE /* BufferChain.m in Sources */,
|
||||||
17D21CA60B8BE4BA00D1EBDE /* InputNode.m in Sources */,
|
17D21CA60B8BE4BA00D1EBDE /* InputNode.m in Sources */,
|
||||||
|
831A50112865A7DC0049CFE4 /* r8bbase.cpp in Sources */,
|
||||||
83504166286447DA006B32CC /* Downmix.m in Sources */,
|
83504166286447DA006B32CC /* Downmix.m in Sources */,
|
||||||
8399CF2D27B5D1D5008751F1 /* NSDictionary+Merge.m in Sources */,
|
8399CF2D27B5D1D5008751F1 /* NSDictionary+Merge.m in Sources */,
|
||||||
|
831A50162865A8800049CFE4 /* r8bstate.cpp in Sources */,
|
||||||
17D21CA80B8BE4BA00D1EBDE /* Node.m in Sources */,
|
17D21CA80B8BE4BA00D1EBDE /* Node.m in Sources */,
|
||||||
17D21CAA0B8BE4BA00D1EBDE /* OutputNode.m in Sources */,
|
17D21CAA0B8BE4BA00D1EBDE /* OutputNode.m in Sources */,
|
||||||
8377C65327B8CAD100E8BC0F /* VisualizationController.m in Sources */,
|
8377C65327B8CAD100E8BC0F /* VisualizationController.m in Sources */,
|
||||||
|
@ -545,6 +683,8 @@
|
||||||
839366681815923C006DD712 /* CogPluginMulti.m in Sources */,
|
839366681815923C006DD712 /* CogPluginMulti.m in Sources */,
|
||||||
17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */,
|
17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */,
|
||||||
17F94DD60B8D0F7000A34E87 /* PluginController.mm in Sources */,
|
17F94DD60B8D0F7000A34E87 /* PluginController.mm in Sources */,
|
||||||
|
831A4FE62865A7DC0049CFE4 /* pffft_double.c in Sources */,
|
||||||
|
831A4FF22865A7DC0049CFE4 /* CDSPHBUpsampler.inc in Sources */,
|
||||||
17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */,
|
17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */,
|
||||||
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */,
|
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */,
|
||||||
17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */,
|
17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */,
|
||||||
|
@ -578,10 +718,17 @@
|
||||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
|
"R8B_EXTFFT=1",
|
||||||
|
"R8B_PFFFT_DOUBLE=1",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/ThirdParty/r8brain-free-src/DLL/Win64",
|
||||||
|
"$(PROJECT_DIR)/ThirdParty/r8brain-free-src/DLL/Win32",
|
||||||
|
);
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||||
PRODUCT_NAME = CogAudio;
|
PRODUCT_NAME = CogAudio;
|
||||||
|
@ -606,10 +753,17 @@
|
||||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"R8B_EXTFFT=1",
|
||||||
|
"R8B_PFFFT_DOUBLE=1",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/ThirdParty/r8brain-free-src/DLL/Win64",
|
||||||
|
"$(PROJECT_DIR)/ThirdParty/r8brain-free-src/DLL/Win32",
|
||||||
|
);
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||||
PRODUCT_NAME = CogAudio;
|
PRODUCT_NAME = CogAudio;
|
||||||
|
|
|
@ -36,6 +36,9 @@ using std::atomic_long;
|
||||||
@interface OutputAVFoundation : NSObject {
|
@interface OutputAVFoundation : NSObject {
|
||||||
OutputNode *outputController;
|
OutputNode *outputController;
|
||||||
|
|
||||||
|
BOOL r8bFlushing, r8bFlushed, r8bDone;
|
||||||
|
void *r8bstate, *r8bold;
|
||||||
|
|
||||||
BOOL stopInvoked;
|
BOOL stopInvoked;
|
||||||
BOOL running;
|
BOOL running;
|
||||||
BOOL stopping;
|
BOOL stopping;
|
||||||
|
@ -64,6 +67,7 @@ using std::atomic_long;
|
||||||
|
|
||||||
AudioDeviceID outputDeviceID;
|
AudioDeviceID outputDeviceID;
|
||||||
AudioStreamBasicDescription streamFormat; // stream format last seen in render callback
|
AudioStreamBasicDescription streamFormat; // stream format last seen in render callback
|
||||||
|
AudioStreamBasicDescription newFormat; // in case of resampler flush
|
||||||
|
|
||||||
AudioStreamBasicDescription visFormat; // Mono format for vis
|
AudioStreamBasicDescription visFormat; // Mono format for vis
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#import <Accelerate/Accelerate.h>
|
#import <Accelerate/Accelerate.h>
|
||||||
|
|
||||||
|
#import "r8bstate.h"
|
||||||
|
|
||||||
extern void scale_by_volume(float *buffer, size_t count, float volume);
|
extern void scale_by_volume(float *buffer, size_t count, float volume);
|
||||||
|
|
||||||
static NSString *CogPlaybackDidBeginNotficiation = @"CogPlaybackDidBeginNotficiation";
|
static NSString *CogPlaybackDidBeginNotficiation = @"CogPlaybackDidBeginNotficiation";
|
||||||
|
@ -84,19 +86,41 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA
|
||||||
BOOL formatClipped = NO;
|
BOOL formatClipped = NO;
|
||||||
BOOL isSurround = format.mChannelsPerFrame > 2;
|
BOOL isSurround = format.mChannelsPerFrame > 2;
|
||||||
const double maxSampleRate = isSurround ? 352800.0 : 192000.0;
|
const double maxSampleRate = isSurround ? 352800.0 : 192000.0;
|
||||||
|
double srcRate = format.mSampleRate;
|
||||||
|
double dstRate = srcRate;
|
||||||
if(format.mSampleRate > maxSampleRate) {
|
if(format.mSampleRate > maxSampleRate) {
|
||||||
format.mSampleRate = maxSampleRate;
|
format.mSampleRate = maxSampleRate;
|
||||||
|
dstRate = maxSampleRate;
|
||||||
formatClipped = YES;
|
formatClipped = YES;
|
||||||
}
|
}
|
||||||
if(!streamFormatStarted || config != streamChannelConfig || memcmp(&streamFormat, &format, sizeof(format)) != 0) {
|
if(!streamFormatStarted || config != streamChannelConfig || memcmp(&newFormat, &format, sizeof(format)) != 0) {
|
||||||
if(formatClipped) {
|
if(formatClipped) {
|
||||||
ALog(@"Sample rate clipped to no more than %f Hz!", maxSampleRate);
|
ALog(@"Sample rate clipped to no more than %f Hz!", maxSampleRate);
|
||||||
|
if(r8bstate) {
|
||||||
|
r8bold = r8bstate;
|
||||||
|
r8bstate = NULL;
|
||||||
|
r8bFlushing = YES;
|
||||||
|
}
|
||||||
|
r8bstate = r8bstate_new(format.mChannelsPerFrame, 1024, srcRate, dstRate);
|
||||||
|
} else if(r8bstate) {
|
||||||
|
r8bold = r8bstate;
|
||||||
|
r8bstate = NULL;
|
||||||
|
r8bFlushing = YES;
|
||||||
}
|
}
|
||||||
streamFormat = format;
|
newFormat = format;
|
||||||
streamChannelConfig = config;
|
streamChannelConfig = config;
|
||||||
streamFormatStarted = YES;
|
streamFormatStarted = YES;
|
||||||
[self updateStreamFormat];
|
|
||||||
|
visFormat = format;
|
||||||
|
visFormat.mChannelsPerFrame = 1;
|
||||||
|
visFormat.mBytesPerFrame = visFormat.mChannelsPerFrame * (visFormat.mBitsPerChannel / 8);
|
||||||
|
visFormat.mBytesPerPacket = visFormat.mBytesPerFrame * visFormat.mFramesPerPacket;
|
||||||
|
|
||||||
downmixerForVis = [[DownmixProcessor alloc] initWithInputFormat:format inputConfig:config andOutputFormat:visFormat outputConfig:AudioConfigMono];
|
downmixerForVis = [[DownmixProcessor alloc] initWithInputFormat:format inputConfig:config andOutputFormat:visFormat outputConfig:AudioConfigMono];
|
||||||
|
if(!r8bold) {
|
||||||
|
streamFormat = format;
|
||||||
|
[self updateStreamFormat];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkDuration = [chunk duration];
|
chunkDuration = [chunk duration];
|
||||||
|
@ -107,13 +131,24 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA
|
||||||
amount:frameCount * format.mChannelsPerFrame
|
amount:frameCount * format.mChannelsPerFrame
|
||||||
location:@"pre downmix"];
|
location:@"pre downmix"];
|
||||||
#endif
|
#endif
|
||||||
|
// It should be fine to request up to double, we'll only get downsampled
|
||||||
|
float outputBuffer[2048 * newFormat.mChannelsPerFrame];
|
||||||
|
const float *outputPtr = (const float *)[samples bytes];
|
||||||
|
if(r8bstate) {
|
||||||
|
size_t inDone = 0;
|
||||||
|
size_t framesDone = r8bstate_resample(r8bstate, outputPtr, frameCount, &inDone, &outputBuffer[0], 2048);
|
||||||
|
if(!framesDone) return 0;
|
||||||
|
frameCount = (int)framesDone;
|
||||||
|
outputPtr = &outputBuffer[0];
|
||||||
|
chunkDuration = frameCount / newFormat.mSampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
[downmixerForVis process:[samples bytes]
|
[downmixerForVis process:outputPtr
|
||||||
frameCount:frameCount
|
frameCount:frameCount
|
||||||
output:visAudio];
|
output:visAudio];
|
||||||
visTabulated += frameCount;
|
visTabulated += frameCount;
|
||||||
|
|
||||||
cblas_scopy((int)(frameCount * streamFormat.mChannelsPerFrame), (const float *)[samples bytes], 1, &inputBuffer[0], 1);
|
cblas_scopy((int)(frameCount * newFormat.mChannelsPerFrame), outputPtr, 1, &inputBuffer[0], 1);
|
||||||
amountRead = frameCount;
|
amountRead = frameCount;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -141,9 +176,9 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA
|
||||||
volumeScale *= eqPreamp;
|
volumeScale *= eqPreamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
scale_by_volume(&inputBuffer[0], amountRead * streamFormat.mChannelsPerFrame, volumeScale);
|
scale_by_volume(&inputBuffer[0], amountRead * newFormat.mChannelsPerFrame, volumeScale);
|
||||||
|
|
||||||
[visController postSampleRate:streamFormat.mSampleRate];
|
[visController postSampleRate:newFormat.mSampleRate];
|
||||||
[visController postVisPCM:visAudio amount:visTabulated];
|
[visController postVisPCM:visAudio amount:visTabulated];
|
||||||
|
|
||||||
return amountRead;
|
return amountRead;
|
||||||
|
@ -222,6 +257,14 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)processEndOfStream {
|
||||||
|
if([outputController endOfStream] == YES && [self signalEndOfStream:secondsLatency]) {
|
||||||
|
stopping = YES;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)threadEntry:(id)arg {
|
- (void)threadEntry:(id)arg {
|
||||||
running = YES;
|
running = YES;
|
||||||
started = NO;
|
started = NO;
|
||||||
|
@ -258,20 +301,8 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
|
|
||||||
[audioRenderer enqueueSampleBuffer:bufferRef];
|
[audioRenderer enqueueSampleBuffer:bufferRef];
|
||||||
} else {
|
} else {
|
||||||
if([outputController endOfStream] == YES && ![self signalEndOfStream:secondsLatency]) {
|
|
||||||
// Wait for output to catch up
|
|
||||||
CMTime currentTime;
|
|
||||||
[currentPtsLock lock];
|
|
||||||
currentTime = currentPts;
|
|
||||||
[currentPtsLock unlock];
|
|
||||||
CMTime timeToWait = CMTimeSubtract(outputPts, currentTime);
|
|
||||||
double secondsToWait = CMTimeGetSeconds(timeToWait);
|
|
||||||
if(secondsToWait > 0) {
|
|
||||||
usleep(secondsToWait * 1000000.0);
|
|
||||||
}
|
|
||||||
stopping = YES;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
// r8b will absorb some samples first
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,11 +529,6 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateStreamFormat {
|
- (void)updateStreamFormat {
|
||||||
visFormat = streamFormat;
|
|
||||||
visFormat.mChannelsPerFrame = 1;
|
|
||||||
visFormat.mBytesPerFrame = visFormat.mChannelsPerFrame * (visFormat.mBitsPerChannel / 8);
|
|
||||||
visFormat.mBytesPerPacket = visFormat.mBytesPerFrame * visFormat.mFramesPerPacket;
|
|
||||||
|
|
||||||
/* Set the channel layout for the audio queue */
|
/* Set the channel layout for the audio queue */
|
||||||
AudioChannelLayoutTag tag = 0;
|
AudioChannelLayoutTag tag = 0;
|
||||||
AudioChannelLayout layout = { 0 };
|
AudioChannelLayout layout = { 0 };
|
||||||
|
@ -598,62 +624,114 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
status = CMBlockBufferCreateEmpty(kCFAllocatorDefault, 0, 0, &blockListBuffer);
|
status = CMBlockBufferCreateEmpty(kCFAllocatorDefault, 0, 0, &blockListBuffer);
|
||||||
if(status != noErr || !blockListBuffer) return 0;
|
if(status != noErr || !blockListBuffer) return 0;
|
||||||
|
|
||||||
int samplesRendered = [self renderInput];
|
int inputRendered;
|
||||||
|
do {
|
||||||
|
inputRendered = [self renderInput];
|
||||||
|
if([self processEndOfStream]) break;
|
||||||
|
} while(!inputRendered);
|
||||||
|
|
||||||
if(samplesRendered) {
|
float tempBuffer[2048 * 32];
|
||||||
if(eqEnabled) {
|
|
||||||
const int channels = streamFormat.mChannelsPerFrame;
|
|
||||||
if(channels > 0) {
|
|
||||||
const size_t channelsminusone = channels - 1;
|
|
||||||
uint8_t tempBuffer[sizeof(AudioBufferList) + sizeof(AudioBuffer) * channelsminusone];
|
|
||||||
AudioBufferList *ioData = (AudioBufferList *)&tempBuffer[0];
|
|
||||||
|
|
||||||
ioData->mNumberBuffers = channels;
|
int samplesRenderedTotal = 0;
|
||||||
for(size_t i = 0; i < channels; ++i) {
|
|
||||||
ioData->mBuffers[i].mData = &eqBuffer[1024 * i];
|
|
||||||
ioData->mBuffers[i].mDataByteSize = 1024 * sizeof(float);
|
|
||||||
ioData->mBuffers[i].mNumberChannels = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = AudioUnitRender(_eq, NULL, &timeStamp, 0, samplesRendered, ioData);
|
for(size_t i = 0; i < 2;) {
|
||||||
|
float *samplePtr;
|
||||||
|
int samplesRendered;
|
||||||
|
|
||||||
if(status != noErr) {
|
if(i == 0) {
|
||||||
return 0;
|
if(!r8bold) {
|
||||||
}
|
++i;
|
||||||
|
continue;
|
||||||
timeStamp.mSampleTime += ((double)samplesRendered) / streamFormat.mSampleRate;
|
}
|
||||||
|
samplesRendered = r8bstate_flush(r8bold, &tempBuffer[0], 2048);
|
||||||
for(int i = 0; i < channels; ++i) {
|
if(!samplesRendered) {
|
||||||
cblas_scopy(samplesRendered, &eqBuffer[1024 * i], 1, &inputBuffer[i], channels);
|
r8bstate_delete(r8bold);
|
||||||
}
|
r8bold = NULL;
|
||||||
|
r8bDone = YES;
|
||||||
|
}
|
||||||
|
samplePtr = &tempBuffer[0];
|
||||||
|
} else {
|
||||||
|
samplesRendered = inputRendered;
|
||||||
|
samplePtr = &inputBuffer[0];
|
||||||
|
if(r8bDone) {
|
||||||
|
r8bDone = NO;
|
||||||
|
streamFormat = newFormat;
|
||||||
|
[self updateStreamFormat];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CMBlockBufferRef blockBuffer = nil;
|
if(samplesRendered) {
|
||||||
size_t dataByteSize = samplesRendered * sizeof(float) * streamFormat.mChannelsPerFrame;
|
if(eqEnabled) {
|
||||||
|
const int channels = streamFormat.mChannelsPerFrame;
|
||||||
|
if(channels > 0) {
|
||||||
|
const size_t channelsminusone = channels - 1;
|
||||||
|
uint8_t tempBuffer[sizeof(AudioBufferList) + sizeof(AudioBuffer) * channelsminusone];
|
||||||
|
AudioBufferList *ioData = (AudioBufferList *)&tempBuffer[0];
|
||||||
|
|
||||||
status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, nil, dataByteSize, kCFAllocatorDefault, nil, 0, dataByteSize, kCMBlockBufferAssureMemoryNowFlag, &blockBuffer);
|
ioData->mNumberBuffers = channels;
|
||||||
|
for(size_t i = 0; i < channels; ++i) {
|
||||||
|
ioData->mBuffers[i].mData = &eqBuffer[1024 * i];
|
||||||
|
ioData->mBuffers[i].mDataByteSize = 1024 * sizeof(float);
|
||||||
|
ioData->mBuffers[i].mNumberChannels = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(status != noErr || !blockBuffer) {
|
status = AudioUnitRender(_eq, NULL, &timeStamp, 0, samplesRendered, ioData);
|
||||||
return 0;
|
|
||||||
|
if(status != noErr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeStamp.mSampleTime += ((double)samplesRendered) / streamFormat.mSampleRate;
|
||||||
|
|
||||||
|
for(int i = 0; i < channels; ++i) {
|
||||||
|
cblas_scopy(samplesRendered, &eqBuffer[1024 * i], 1, samplePtr, channels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMBlockBufferRef blockBuffer = nil;
|
||||||
|
size_t dataByteSize = samplesRendered * sizeof(float) * streamFormat.mChannelsPerFrame;
|
||||||
|
|
||||||
|
status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, nil, dataByteSize, kCFAllocatorDefault, nil, 0, dataByteSize, kCMBlockBufferAssureMemoryNowFlag, &blockBuffer);
|
||||||
|
|
||||||
|
if(status != noErr || !blockBuffer) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = CMBlockBufferReplaceDataBytes(samplePtr, blockBuffer, 0, dataByteSize);
|
||||||
|
|
||||||
|
if(status != noErr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = CMBlockBufferAppendBufferReference(blockListBuffer, blockBuffer, 0, CMBlockBufferGetDataLength(blockBuffer), 0);
|
||||||
|
|
||||||
|
if(status != noErr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = CMBlockBufferReplaceDataBytes(&inputBuffer[0], blockBuffer, 0, dataByteSize);
|
if(i == 0) {
|
||||||
|
if(!samplesRendered) {
|
||||||
if(status != noErr) {
|
*blockBufferOut = blockListBuffer;
|
||||||
return 0;
|
return samplesRenderedTotal + samplesRendered;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
status = CMBlockBufferAppendBufferReference(blockListBuffer, blockBuffer, 0, CMBlockBufferGetDataLength(blockBuffer), 0);
|
samplesRenderedTotal += samplesRendered;
|
||||||
|
if(!samplesRendered || samplesRenderedTotal >= 1024) {
|
||||||
if(status != noErr) {
|
++i;
|
||||||
return 0;
|
} else {
|
||||||
|
do {
|
||||||
|
inputRendered = [self renderInput];
|
||||||
|
if([self processEndOfStream]) break;
|
||||||
|
} while(!inputRendered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*blockBufferOut = blockListBuffer;
|
*blockBufferOut = blockListBuffer;
|
||||||
|
|
||||||
return samplesRendered;
|
return samplesRenderedTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)setup {
|
- (BOOL)setup {
|
||||||
|
@ -672,6 +750,12 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
|
|
||||||
downmixerForVis = nil;
|
downmixerForVis = nil;
|
||||||
|
|
||||||
|
r8bFlushing = NO;
|
||||||
|
r8bFlushed = NO;
|
||||||
|
r8bDone = NO;
|
||||||
|
r8bstate = NULL;
|
||||||
|
r8bold = NULL;
|
||||||
|
|
||||||
AudioComponentDescription desc;
|
AudioComponentDescription desc;
|
||||||
NSError *err;
|
NSError *err;
|
||||||
|
|
||||||
|
@ -907,6 +991,14 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
#endif
|
#endif
|
||||||
outputController = nil;
|
outputController = nil;
|
||||||
visController = nil;
|
visController = nil;
|
||||||
|
if(r8bstate) {
|
||||||
|
r8bstate_delete(r8bstate);
|
||||||
|
r8bstate = NULL;
|
||||||
|
}
|
||||||
|
if(r8bold) {
|
||||||
|
r8bstate_delete(r8bold);
|
||||||
|
r8bold = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit afd61e7ed76d86a9bc6cb91fd0a9f305f853fe38
|
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// r8bstate.cpp
|
||||||
|
// CogAudio Framework
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 6/24/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "r8bstate.h"
|
||||||
|
#include "r8bstate.hpp"
|
||||||
|
|
||||||
|
void *r8bstate_new(int channelCount, int bufferCapacity, double srcRate,
|
||||||
|
double dstRate) {
|
||||||
|
return (void *)new r8bstate(channelCount, bufferCapacity, srcRate, dstRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void r8bstate_delete(void *state) {
|
||||||
|
delete(r8bstate *)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
double r8bstate_latency(void *state) {
|
||||||
|
return ((r8bstate *)state)->latency();
|
||||||
|
}
|
||||||
|
|
||||||
|
int r8bstate_resample(void *state, const float *input, size_t inCount, size_t *inDone,
|
||||||
|
float *output, size_t outMax) {
|
||||||
|
return ((r8bstate *)state)->resample(input, inCount, inDone, output, outMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
int r8bstate_flush(void *state, float *output, size_t outMax) {
|
||||||
|
return ((r8bstate *)state)->flush(output, outMax);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
//
|
||||||
|
// r8bstate.h
|
||||||
|
// CogAudio Framework
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 6/24/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef r8bstate_h
|
||||||
|
#define r8bstate_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *r8bstate_new(int channelCount, int bufferCapacity, double srcRate,
|
||||||
|
double dstRate);
|
||||||
|
void r8bstate_delete(void *);
|
||||||
|
|
||||||
|
double r8bstate_latency(void *);
|
||||||
|
|
||||||
|
int r8bstate_resample(void *, const float *input, size_t inCount, size_t *inDone,
|
||||||
|
float *output, size_t outMax);
|
||||||
|
|
||||||
|
int r8bstate_flush(void *, float *output, size_t outMax);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* r8bstate_h */
|
|
@ -0,0 +1,164 @@
|
||||||
|
//
|
||||||
|
// r8bstate.hpp
|
||||||
|
// CogAudio Framework
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 3/3/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef r8bstate_hpp
|
||||||
|
#define r8bstate_hpp
|
||||||
|
|
||||||
|
#include <Accelerate/Accelerate.h>
|
||||||
|
|
||||||
|
#include "r8bbase.h"
|
||||||
|
|
||||||
|
#include "CDSPResampler.h"
|
||||||
|
|
||||||
|
struct r8bstate {
|
||||||
|
int channelCount;
|
||||||
|
int bufferCapacity;
|
||||||
|
size_t remainder;
|
||||||
|
uint64_t inProcessed;
|
||||||
|
uint64_t outProcessed;
|
||||||
|
double sampleRatio;
|
||||||
|
r8b::CFixedBuffer<double> InBuf;
|
||||||
|
r8b::CFixedBuffer<double> *OutBufs;
|
||||||
|
r8b::CDSPResampler24 **Resamps;
|
||||||
|
r8bstate(int _channelCount, int _bufferCapacity, double srcRate, double dstRate)
|
||||||
|
: channelCount(_channelCount), bufferCapacity(_bufferCapacity), inProcessed(0), outProcessed(0), remainder(0) {
|
||||||
|
InBuf.alloc(bufferCapacity);
|
||||||
|
OutBufs = new r8b::CFixedBuffer<double>[channelCount];
|
||||||
|
Resamps = new r8b::CDSPResampler24 *[channelCount];
|
||||||
|
for(int i = 0; i < channelCount; ++i) {
|
||||||
|
Resamps[i] = new r8b::CDSPResampler24(srcRate, dstRate, bufferCapacity);
|
||||||
|
}
|
||||||
|
sampleRatio = dstRate / srcRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
~r8bstate() {
|
||||||
|
delete[] OutBufs;
|
||||||
|
for(int i = 0; i < channelCount; ++i) {
|
||||||
|
delete Resamps[i];
|
||||||
|
}
|
||||||
|
delete[] Resamps;
|
||||||
|
}
|
||||||
|
|
||||||
|
double latency() {
|
||||||
|
return ((double)inProcessed * sampleRatio) - (double)outProcessed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resample(const float *input, size_t inCount, size_t *inDone, float *output, size_t outMax) {
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
if(inDone) *inDone = 0;
|
||||||
|
while(remainder > 0) {
|
||||||
|
size_t blockCount = remainder;
|
||||||
|
if(blockCount > outMax)
|
||||||
|
blockCount = outMax;
|
||||||
|
for(i = 0; i < channelCount; ++i) {
|
||||||
|
vDSP_vdpsp(&OutBufs[i][0], 1, output + i, channelCount, blockCount);
|
||||||
|
}
|
||||||
|
remainder -= blockCount;
|
||||||
|
if(remainder > 0) {
|
||||||
|
for(i = 0; i < channelCount; ++i) {
|
||||||
|
memmove(&OutBufs[i][0], &OutBufs[i][blockCount], remainder * sizeof(double));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += channelCount * blockCount;
|
||||||
|
outProcessed += blockCount;
|
||||||
|
outMax -= blockCount;
|
||||||
|
ret += blockCount;
|
||||||
|
if(!outMax)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
while(inCount > 0) {
|
||||||
|
size_t blockCount = inCount;
|
||||||
|
if(blockCount > bufferCapacity)
|
||||||
|
blockCount = bufferCapacity;
|
||||||
|
int outputDone = 0;
|
||||||
|
for(i = 0; i < channelCount; ++i) {
|
||||||
|
double *outputPointer;
|
||||||
|
vDSP_vspdp(input + i, channelCount, &InBuf[0], 1, blockCount);
|
||||||
|
outputDone = Resamps[i]->process(InBuf, (int)blockCount, outputPointer);
|
||||||
|
if(outputDone) {
|
||||||
|
if(outputDone > outMax) {
|
||||||
|
vDSP_vdpsp(outputPointer, 1, output + i, channelCount, outMax);
|
||||||
|
remainder = outputDone - outMax;
|
||||||
|
OutBufs[i].alloc((int)remainder);
|
||||||
|
memcpy(&OutBufs[i][0], outputPointer + outMax, remainder);
|
||||||
|
} else {
|
||||||
|
vDSP_vdpsp(outputPointer, 1, output + i, channelCount, outputDone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t outputActual = outputDone - remainder;
|
||||||
|
input += channelCount * blockCount;
|
||||||
|
output += channelCount * outputActual;
|
||||||
|
inCount -= blockCount;
|
||||||
|
if(inDone) *inDone += blockCount;
|
||||||
|
inProcessed += blockCount;
|
||||||
|
outProcessed += outputActual;
|
||||||
|
outMax -= outputActual;
|
||||||
|
ret += outputActual;
|
||||||
|
if(remainder)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flush(float *output, size_t outMax) {
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
if(remainder > 0) {
|
||||||
|
size_t blockCount = remainder;
|
||||||
|
if(blockCount > outMax)
|
||||||
|
blockCount = outMax;
|
||||||
|
for(i = 0; i < channelCount; ++i) {
|
||||||
|
vDSP_vdpsp(&OutBufs[i][0], 1, output + i, channelCount, blockCount);
|
||||||
|
}
|
||||||
|
remainder -= blockCount;
|
||||||
|
if(remainder > 0) {
|
||||||
|
for(i = 0; i < channelCount; ++i) {
|
||||||
|
memmove(&OutBufs[i][0], &OutBufs[i][blockCount], remainder * sizeof(double));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += channelCount * blockCount;
|
||||||
|
outProcessed += blockCount;
|
||||||
|
outMax -= blockCount;
|
||||||
|
ret += blockCount;
|
||||||
|
if(!outMax)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
uint64_t outputWanted = ceil(inProcessed * sampleRatio);
|
||||||
|
memset(&InBuf[0], 0, sizeof(double) * bufferCapacity);
|
||||||
|
while(outProcessed < outputWanted) {
|
||||||
|
int outputDone = 0;
|
||||||
|
for(int i = 0; i < channelCount; ++i) {
|
||||||
|
double *outputPointer;
|
||||||
|
outputDone = Resamps[i]->process(InBuf, bufferCapacity, outputPointer);
|
||||||
|
if(outputDone) {
|
||||||
|
if(outputDone > (outputWanted - outProcessed))
|
||||||
|
outputDone = (int)(outputWanted - outProcessed);
|
||||||
|
if(outputDone > outMax) {
|
||||||
|
vDSP_vdpsp(outputPointer, 1, output + i, channelCount, outMax);
|
||||||
|
remainder = outputDone - outMax;
|
||||||
|
OutBufs[i].alloc((int)remainder);
|
||||||
|
memcpy(&OutBufs[i][0], outputPointer + outMax, remainder);
|
||||||
|
} else {
|
||||||
|
vDSP_vdpsp(outputPointer, 1, output + i, channelCount, outputDone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t outputActual = outputDone - remainder;
|
||||||
|
outProcessed += outputActual;
|
||||||
|
output += channelCount * outputActual;
|
||||||
|
outMax -= outputActual;
|
||||||
|
ret += outputActual;
|
||||||
|
if(remainder)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* r8bstate_h */
|
Loading…
Reference in New Issue