From 4fcf8c251c7c0b34dfcfbeab04cda6819561eb40 Mon Sep 17 00:00:00 2001 From: Hipreme Date: Tue, 12 Dec 2023 21:41:13 -0300 Subject: [PATCH 1/5] Added: New dependency versions, initial AVAudioEngine files --- dependencies/avaudioengine | 2 +- dependencies/objc | 2 +- modules/audio/dub.json | 9 + modules/audio/source/hip/hipaudio/audio.d | 154 ++++++++++-------- .../hip/hipaudio/backend/avaudio/clip.d | 49 ++++++ .../hip/hipaudio/backend/avaudio/player.d | 87 ++++++++++ .../hip/hipaudio/backend/avaudio/source.d | 70 ++++++++ modules/audio/source/hip/hipaudio/config.d | 16 ++ tools/build/targets/ios/dub.template.json | 3 +- 9 files changed, 319 insertions(+), 73 deletions(-) create mode 100644 modules/audio/source/hip/hipaudio/backend/avaudio/clip.d create mode 100644 modules/audio/source/hip/hipaudio/backend/avaudio/player.d create mode 100644 modules/audio/source/hip/hipaudio/backend/avaudio/source.d create mode 100644 modules/audio/source/hip/hipaudio/config.d diff --git a/dependencies/avaudioengine b/dependencies/avaudioengine index 797aa8d53..fd203458d 160000 --- a/dependencies/avaudioengine +++ b/dependencies/avaudioengine @@ -1 +1 @@ -Subproject commit 797aa8d53d1221addec591c841ae42c3f9baee62 +Subproject commit fd203458d91cbd1339aa67455250479b45ea25b1 diff --git a/dependencies/objc b/dependencies/objc index 0b9ebe09b..fb23fe027 160000 --- a/dependencies/objc +++ b/dependencies/objc @@ -1 +1 @@ -Subproject commit 0b9ebe09b3ac06b848702f5706386b9fd20e8fb3 +Subproject commit fb23fe027c17a19fcfcfc472ae495c8e26d94c6c diff --git a/modules/audio/dub.json b/modules/audio/dub.json index 842278626..908b24e17 100644 --- a/modules/audio/dub.json +++ b/modules/audio/dub.json @@ -80,6 +80,15 @@ "bindbc-openal": "static" } }, + { + "name": "ios", + "dependencies": { + "avaudioengine": {"path": "../../dependencies/avaudioengine"} + }, + "subConfigurations": { + "audio_decoding": "audioformats" + } + }, { "name": "android", "dependencies": {"sles": {"path": "../../dependencies/sles", "version": "*"}}, diff --git a/modules/audio/source/hip/hipaudio/audio.d b/modules/audio/source/hip/hipaudio/audio.d index 5deddaa0d..cb5521b0c 100644 --- a/modules/audio/source/hip/hipaudio/audio.d +++ b/modules/audio/source/hip/hipaudio/audio.d @@ -13,12 +13,15 @@ module hip.hipaudio.audio; public import hip.hipaudio.audioclip; public import hip.hipaudio.audiosource; public import hip.api.audio; +import hip.hipaudio.config; //Backends -version(OpenAL){import hip.hipaudio.backend.openal.player;} -version(Android){import hip.hipaudio.backend.opensles.player;} -version(XAudio2){import hip.hipaudio.backend.xaudio.player;} -version(NullAudio){import hip.hipaudio.backend.nullaudio;} + +static if(HasOpenAL){import hip.hipaudio.backend.openal.player;} +static if(HasOpenSLES){import hip.hipaudio.backend.opensles.player;} +static if(HasXAudio2){import hip.hipaudio.backend.xaudio.player;} +static if(HasAVAudioEngine){import hip.hipaudio.backend.avaudio.player;} +import hip.hipaudio.backend.nullaudio; import hip.audio_decoding.audio; @@ -57,74 +60,16 @@ public interface IHipAudioPlayer class HipAudio { - public static bool initialize(HipAudioImplementation implementation = HipAudioImplementation.OPENAL, + public static bool initialize(HipAudioImplementation implementation = HipAudioImplementation.OpenAL, bool hasProAudio = false, bool hasLowLatencyAudio = false, int optimalBufferSize = 4096, int optimalSampleRate = 44_100) { ErrorHandler.startListeningForErrors("HipremeAudio initialization"); - version(HIPREME_DEBUG) - { - hasInitializedAudio = true; - } - import hip.console.log; + _hasInitializedAudio = true; HipAudio.is3D = is3D; - - final switch(implementation) - { - case HipAudioImplementation.OPENSLES: - version(Android) - { - audioInterface = new HipOpenSLESAudioPlayer(AudioConfig.androidConfig, - hasProAudio, - hasLowLatencyAudio, - optimalBufferSize, - optimalSampleRate); - break; - } - case HipAudioImplementation.XAUDIO2: - version(XAudio2) - { - loglnInfo("Initializing XAudio2 with audio config ", AudioConfig.musicConfig); - audioInterface = new HipXAudioPlayer(AudioConfig.musicConfig); - break; - } - else - { - loglnWarn("Tried to use XAudio2 implementation, but no XAudio2 version was provided. OpenAL will be used instead"); - goto case HipAudioImplementation.OPENAL; - } - case HipAudioImplementation.OPENAL: - { - version(OpenAL) - { - //Please note that OpenAL HRTF(spatial sound) only works with Mono Channel - audioInterface = new HipOpenALAudioPlayer(AudioConfig.musicConfig); - // audioInterface = new HipNullAudio(); - break; - } - else - { - loglnWarn("Tried to use OpenAL implementation, but no OpenAL version was provided. No audio available."); - break; - } - } - case HipAudioImplementation.WEBAUDIO: - { - version(WebAssembly) - { - import hip.hipaudio.backend.nullaudio; - audioInterface = new HipWebAudioPlayer(AudioConfig.musicConfig); - break; - } - else - { - loglnWarn("Tried to use WebAudio implementation, but not in WebAssembly. No audio available"); - break; - } - } - } + audioInterface = getAudioInterface(implementation); HipAudio.hasProAudio = hasProAudio; HipAudio.hasLowLatencyAudio = hasLowLatencyAudio; HipAudio.optimalBufferSize = optimalBufferSize; @@ -179,6 +124,79 @@ class HipAudio audioInterface.update(); } + private static IHipAudioPlayer getAudioInterface(HipAudioImplementation impl, + bool hasProAudio = false, + bool hasLowLatencyAudio = false, + int optimalBufferSize = 4096, + int optimalSampleRate = 44_100) + { + import hip.console.log; + final switch(impl) + { + case HipAudioImplementation.WebAudio: + { + version(WebAssembly) + { + return new HipWebAudioPlayer(AudioConfig.musicConfig); + } + else + { + loglnWarn("Tried to use WebAudio implementation, but not in WebAssembly. No audio available"); + goto case HipAudioImplementation.Null; + } + } + case HipAudioImplementation.OpenSLES: + static if(HasOpenSLES) + { + return new HipOpenSLESAudioPlayer(AudioConfig.androidConfig, + hasProAudio, + hasLowLatencyAudio, + optimalBufferSize, + optimalSampleRate); + break; + } + case HipAudioImplementation.XAudio2: + static if(HasXAudio2) + { + loglnInfo("Initializing XAudio2 with audio config ", AudioConfig.musicConfig); + return new HipXAudioPlayer(AudioConfig.musicConfig); + } + else + { + loglnWarn("Tried to use XAudio2 implementation, but no XAudio2 version was provided. OpenAL will be used instead"); + goto case HipAudioImplementation.OpenAL; + } + case HipAudioImplementation.AVAudioEngine: + { + static if(HasAVAudioEngine) + return new HipAVAudioPlayer(AudioConfig.androidConfig); + else + { + loglnWarn("Tried to use AVAudioEngine implementation, but no AVAudioEngine found. OpenAL will be used instead"); + goto case HipAudioImplementation.OpenAL; + } + } + case HipAudioImplementation.OpenAL: + { + static if(HasOpenAL) + { + //Please note that OpenAL HRTF(spatial sound) only works with Mono Channel + return new HipOpenALAudioPlayer(AudioConfig.musicConfig); + } + else + { + loglnWarn("Tried to use OpenAL implementation, but no OpenAL version was provided. No audio available."); + goto case HipAudioImplementation.Null; + } + } + case HipAudioImplementation.Null: + { + loglnWarn("No AudioInterface was found. Using NullAudio"); + return new HipNullAudio(); + } + } + } + protected __gshared bool hasProAudio; @@ -191,8 +209,6 @@ class HipAudio __gshared IHipAudioPlayer audioInterface; //Debug vars - version(HIPREME_DEBUG) - { - public __gshared bool hasInitializedAudio = false; - } + private __gshared bool _hasInitializedAudio = false; + public bool hasInitializedAudio() => _hasInitializedAudio; } \ No newline at end of file diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d b/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d new file mode 100644 index 000000000..4a1d40936 --- /dev/null +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d @@ -0,0 +1,49 @@ +module hip.hipaudio.backend.avaudio.clip; + +version(iOS): +import avaudiosinknode; +import avaudiobuffer; +import hip.hipaudio.audioclip; +import hip.api.data.audio; +import avaudiosourcenode; +import avaudiobuffer; +import avaudioconverter; + +class HipAVAudioClip : HipAudioClip +{ + AVAudioSourceNode source; + AVAudioBuffer buffer; + AVAudioConverter converter; + + this(IHipAudioDecoder decoder, HipAudioClipHint hint) + { + super(decoder, hint); //TODO: Change num channels + buffer = AVAudioBuffer.alloc.init; + + converter = AVAudioConverter.alloc.initFromFormat( + HipAVAudioPlayer.fromFormat(decoder.getAudioConfig), + HipAVAudioPlayer.fromFormat(HipAVAudioPlayer.getAudioConfig) + ); + } + override void setBufferData(HipAudioBuffer* buffer, ubyte[] data, uint size = 0) + { + } + + ///Nothing to do + override protected void onUpdateStream(ubyte[] data, uint decodedSize){} + + ///Wraps an XAudio buffer + override protected HipAudioBufferWrapper createBuffer(ubyte[] data) + { + HipAudioBufferWrapper ret; // TODO: implement + // ret.buffer.xaudio = &buffer; + return ret; + } + + + ///Calls XAudio2.9 specific buffer destroy + override protected void destroyBuffer(HipAudioBuffer* buffer) + { + + } +} \ No newline at end of file diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/player.d b/modules/audio/source/hip/hipaudio/backend/avaudio/player.d new file mode 100644 index 000000000..aad6b6acd --- /dev/null +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/player.d @@ -0,0 +1,87 @@ +module hip.hipaudio.backend.avaudio.player; + +version(iOS): +public import hip.hipaudio.backend.avaudio.clip; +public import hip.hipaudio.backend.avaudio.source; +public import hip.audio_decoding.audio; +import avaudioengine; +import avaudiomixernode; +import avaudioplayernode; +import hip.hipaudio.audio; +import hip.error.handler; + +class HipAVAudioPlayer : IHipAudioPlayer +{ + AVAudioEngine engine; + AVAudioPlayerNode playerNode; + AVAudioMixerNode mixerNode; + + private static AudioConfig config; + package static AudioConfig getAudioConfig(){return config;} + + /** + * For getting better debug information, you need to run this application on Visual Studio. + * The debug messages actually appears inside the `Output` window. + */ + public this(AudioConfig cfg) + { + HipAVAudioPlayer.config = cfg; + engine = AVAudioEngine.alloc.init; + mixerNode = AVAudioMixerNode.alloc.init; + playerNode = AVAudioPlayerNode.alloc.init; + + engine.attachNode(mixerNode); + engine.attachNode(playerNode); + AVAudioFormat format = fromConfig(cfg); + engine.connect(cast(AVAudioNode)playerNode, cast(AVAudioNode)engine.outputNode, format); + + engine.prepare(); + NSError err; + if(!engine.start(&err)) + ErrorHandler.assertExit(false, "Could not initialize AVAudioEngine: "~err.toString); + } + + public static AVAudioFormat fromConfig(immutable AudioConfig cfg) + { + import hip.util.conv; + AVAudioCommonFormat format; + switch(cfg.format) + { + case AudioFormat.signed16Big: + case AudioFormat.signed16Little: + format = AVAudioCommonFormat.PCMFormatInt16; + break; + case AudioFormat.signed32Big: + case AudioFormat.signed32Little: + format = AVAudioCommonFormat.PCMFormatInt32; + break; + case AudioFormat.float32Big: + case AudioFormat.float32Little: + format = AVAudioCommonFormat.PCMFormatFloat32; + break; + default: + ErrorHandler.assertExit(false, "AVAudioEngine Does not support the current bit depth"); + break; + } + AVAudioFormat fmt = AVAudioFormat.alloc.initWithCommonFormat(format, cfg.sampleRate, cfg.channels, interleaved: cfg.channels == 2 ? true : false); + ErrorHandler.assertLazyExit(fmt !is null, "Could not create audio format with config " ~ cfg.to!string); + return fmt; + } + + public bool play_streamed(AHipAudioSource src){return src.play_streamed();} + + public AHipAudioSource getSource(bool isStreamed){return new HipAVAudioSource(this);} + public IHipAudioClip getClip(){return new HipAVAudioClip(new HipAudioDecoder(), HipAudioClipHint(2, 44_100, false, true));} + + public IHipAudioClip loadStreamed(string audioName, uint chunkSize) + { + ErrorHandler.assertExit(false, "AVAudioPlayer Player does not support chunked decoding"); + return null; + } + public void updateStream(AHipAudioSource source){} + + public void onDestroy() + { + } + public void update(){} +} diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/source.d b/modules/audio/source/hip/hipaudio/backend/avaudio/source.d new file mode 100644 index 000000000..40065963a --- /dev/null +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/source.d @@ -0,0 +1,70 @@ +module hip.hipaudio.backend.avaudio.source; + +version(iOS): +import avaudiosourcenode; +import avaudioplayernode; +import avaudiosinknode; +import avaudioionode; +import hip.error.handler; +import hip.hipaudio.backend.avaudio.player; +import hip.hipaudio.audiosource; + +class HipAVAudioSource : HipAudioSource +{ + AVAudioSinkNode sink; + AVAudioOutputNode output; + + protected bool isClipDirty = true; + + + this(HipAVAudioPlayer player) + { + import hip.util.conv; + output = player.engine.outputNode; + } + alias clip = HipAudioSource.clip; + + + override IHipAudioClip clip(IHipAudioClip newClip) + { + if(newClip != clip) + isClipDirty = true; + super.clip(newClip); + return newClip; + } + + alias loop = HipAudioSource.loop; + override bool loop(bool value) + { + bool ret = super.loop(value); + return ret; + } + + + + override bool play() + { + if(isPlaying) + { + } + + return true; + } + override bool stop() + { + isPlaying = false; + return false; + } + override bool pause() + { + isPaused = true; + return false; + } + override bool play_streamed() => false; + + + ~this() + { + + } +} diff --git a/modules/audio/source/hip/hipaudio/config.d b/modules/audio/source/hip/hipaudio/config.d new file mode 100644 index 000000000..cd7b2e4c2 --- /dev/null +++ b/modules/audio/source/hip/hipaudio/config.d @@ -0,0 +1,16 @@ +module hip.hipaudio.config; + +version(Android) enum HasOpenSLES = true; +else enum HasOpenSLES = false; + +version(XAudio2) enum HasXAudio2 = true; +else enum HasXAudio2 = false; + +version(OpenAL) enum HasOpenAL = true; +else enum HasOpenAL = false; + +version(WebAssembly) enum HasWebAudio = true; +else enum HasWebAudio = false; + +version(iOS) enum HasAVAudioEngine = true; +else enum HasAVAudioEngine = false; \ No newline at end of file diff --git a/tools/build/targets/ios/dub.template.json b/tools/build/targets/ios/dub.template.json index ef1f0d346..afef4c5ba 100644 --- a/tools/build/targets/ios/dub.template.json +++ b/tools/build/targets/ios/dub.template.json @@ -10,10 +10,9 @@ ], "subConfigurations": { "renderer": "appleos", - "audio": "psvita" + "audio": "ios" }, "versions": [ - "OpenAL", "Standalone", "AppleOS" ], From 7d5f903c798fa4d56f4a46aad06c05d28328d332 Mon Sep 17 00:00:00 2001 From: Hipreme Date: Wed, 13 Dec 2023 01:29:15 -0300 Subject: [PATCH 2/5] Update: Initial AVAudioClip implementation --- modules/audio/source/hip/hipaudio/audioclip.d | 14 +++-- .../hip/hipaudio/backend/avaudio/clip.d | 57 +++++++++++++++---- .../hip/hipaudio/backend/avaudio/source.d | 12 ++-- modules/error/source/hip/error/handler.d | 21 +++++-- 4 files changed, 81 insertions(+), 23 deletions(-) diff --git a/modules/audio/source/hip/hipaudio/audioclip.d b/modules/audio/source/hip/hipaudio/audioclip.d index aa1a470e0..ef96e4914 100644 --- a/modules/audio/source/hip/hipaudio/audioclip.d +++ b/modules/audio/source/hip/hipaudio/audioclip.d @@ -19,27 +19,33 @@ public import hip.api.audio.audioclip; union HipAudioBuffer { - version(Have_bindbc_openal) + import hip.hipaudio.config; + static if(HasOpenAL) { import bindbc.openal; ALuint al; } - version(Have_sles) + static if(HasOpenSLES) { import opensles.sles; import hip.hipaudio.backend.sles; SLIBuffer* sles; } - version(Windows) version(Have_directx_d) + static if(HasXAudio2) { import directx.xaudio2; XAUDIO2_BUFFER* xaudio; } - version(WebAssembly) + static if(HasWebAudio) { import hip.hipaudio.backend.webaudio.clip; size_t webaudio; } + static if(HasAVAudioEngine) + { + import hip.hipaudio.backend.avaudio.clip; + AVAudioPCMBuffer avaudio; + } } struct HipAudioBufferWrapper diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d b/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d index 4a1d40936..bf81b6f43 100644 --- a/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d @@ -1,32 +1,69 @@ module hip.hipaudio.backend.avaudio.clip; version(iOS): +public import avaudiobuffer; +public import avaudiotypes; +import objc.runtime; import avaudiosinknode; -import avaudiobuffer; import hip.hipaudio.audioclip; +import hip.hipaudio.backend.avaudio.player; import hip.api.data.audio; import avaudiosourcenode; -import avaudiobuffer; import avaudioconverter; + +extern(C++) void tempDeallocator(const AudioBufferList*) +{ + +} + class HipAVAudioClip : HipAudioClip { AVAudioSourceNode source; - AVAudioBuffer buffer; + AVAudioPCMBuffer buffer; AVAudioConverter converter; this(IHipAudioDecoder decoder, HipAudioClipHint hint) { super(decoder, hint); //TODO: Change num channels - buffer = AVAudioBuffer.alloc.init; - - converter = AVAudioConverter.alloc.initFromFormat( - HipAVAudioPlayer.fromFormat(decoder.getAudioConfig), - HipAVAudioPlayer.fromFormat(HipAVAudioPlayer.getAudioConfig) - ); + buffer = AVAudioPCMBuffer.alloc.init; } override void setBufferData(HipAudioBuffer* buffer, ubyte[] data, uint size = 0) { + if(getHint.needsChannelConversion || getHint.needsDecode || getHint.needsResample) + { + AVAudioFormat rawFormat = HipAVAudioPlayer.fromConfig(decoder.getAudioConfig); + converter = AVAudioConverter.alloc.initFromFormat( + rawFormat, + HipAVAudioPlayer.fromConfig(HipAVAudioPlayer.getAudioConfig) + ); + + AudioBufferList list = AudioBufferList(1, AudioBuffer(decoder.getClipChannels, + cast(uint)getClipSize, getClipData.ptr) + ); + + AVAudioPCMBuffer temp = AVAudioPCMBuffer.alloc.initWithPCMFormat( + rawFormat, &list, &tempDeallocator + ); + + NSError err; + if(!converter.convertToBuffer(this.buffer, temp, &err)) + { + import hip.error.handler; + ErrorHandler.assertExit(false, "Could not convert buffer: "~err.toString); + } + } + else + { + AVAudioFormat rawFormat = HipAVAudioPlayer.fromConfig(decoder.getAudioConfig); + AudioBufferList list = AudioBufferList(1, AudioBuffer(decoder.getClipChannels, + cast(uint)getClipSize, getClipData.ptr) + ); + this.buffer = AVAudioPCMBuffer.alloc.initWithPCMFormat( + rawFormat, &list, &tempDeallocator + ); + } + } ///Nothing to do @@ -36,7 +73,7 @@ class HipAVAudioClip : HipAudioClip override protected HipAudioBufferWrapper createBuffer(ubyte[] data) { HipAudioBufferWrapper ret; // TODO: implement - // ret.buffer.xaudio = &buffer; + ret.buffer.avaudio = buffer; return ret; } diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/source.d b/modules/audio/source/hip/hipaudio/backend/avaudio/source.d index 40065963a..690be4ea4 100644 --- a/modules/audio/source/hip/hipaudio/backend/avaudio/source.d +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/source.d @@ -5,6 +5,7 @@ import avaudiosourcenode; import avaudioplayernode; import avaudiosinknode; import avaudioionode; +import hip.hipaudio.backend.avaudio.clip; import hip.error.handler; import hip.hipaudio.backend.avaudio.player; import hip.hipaudio.audiosource; @@ -12,15 +13,15 @@ import hip.hipaudio.audiosource; class HipAVAudioSource : HipAudioSource { AVAudioSinkNode sink; - AVAudioOutputNode output; + AVAudioPlayerNode player; + AVAudioPCMBuffer buffer; protected bool isClipDirty = true; this(HipAVAudioPlayer player) { - import hip.util.conv; - output = player.engine.outputNode; + this.player = player.playerNode; } alias clip = HipAudioSource.clip; @@ -47,16 +48,19 @@ class HipAVAudioSource : HipAudioSource if(isPlaying) { } - + player.scheduleBuffer(getBufferFromAPI(clip).avaudio); + player.play(); return true; } override bool stop() { + player.stop(); isPlaying = false; return false; } override bool pause() { + player.pause(); isPaused = true; return false; } diff --git a/modules/error/source/hip/error/handler.d b/modules/error/source/hip/error/handler.d index 66caf34bd..b3f019409 100644 --- a/modules/error/source/hip/error/handler.d +++ b/modules/error/source/hip/error/handler.d @@ -15,7 +15,7 @@ import hip.util.conv; /** * Base clas for documenting errors */ - + public class EngineErrorStack { public string stackName; @@ -51,6 +51,19 @@ public class EngineErrorStack } +import core.stdc.stdlib; + +version(iOS) +{ + extern(C) void terminateiOSApp(int code); + ///iOS has a special terminate function which ought to be called when something happens. + alias terminate = terminateiOSApp; +} +else +{ + alias terminate = core.stdc.stdlib.exit; +} + /** * Class Used for handling errors */ @@ -184,8 +197,7 @@ public static class ErrorHandler { cast(void)ErrorHandler.assertErrorMessage(false, "HipAssertion", onAssertionFailure, true, file, line, mod, func); - import core.stdc.stdlib; - exit(EXIT_FAILURE); + terminate(EXIT_FAILURE); } } @@ -196,8 +208,7 @@ public static class ErrorHandler { cast(void)ErrorHandler.assertLazyErrorMessage(false, "HipAssertion", onAssertionFailure, true, file, line, mod, func); - import core.stdc.stdlib; - exit(EXIT_FAILURE); + terminate(EXIT_FAILURE); } } From 68da6e098905d55095169c4039b08a7627587153 Mon Sep 17 00:00:00 2001 From: Hipreme Date: Wed, 13 Dec 2023 18:09:34 -0300 Subject: [PATCH 3/5] Updated: New version containing Objc Block --- dependencies/objc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/objc b/dependencies/objc index fb23fe027..91f220211 160000 --- a/dependencies/objc +++ b/dependencies/objc @@ -1 +1 @@ -Subproject commit fb23fe027c17a19fcfcfc472ae495c8e26d94c6c +Subproject commit 91f2202115556a8b6a43ba1f407b691c551ebfd9 From 87a19dc75476c6d6b522ef4458a5892c1d8cad0e Mon Sep 17 00:00:00 2001 From: Hipreme Date: Wed, 13 Dec 2023 18:29:31 -0300 Subject: [PATCH 4/5] Added: Initial support to audio on iOS --- api/source/hip/api/audio/package.d | 23 ++++++-- .../HipremeEngine.xcodeproj/project.pbxproj | 52 +++++++++++++----- dependencies/avaudioengine | 2 +- .../hip/hipaudio/backend/avaudio/clip.d | 53 ++++++++++++++++--- .../hip/hipaudio/backend/avaudio/player.d | 2 +- .../hip/hipaudio/backend/avaudio/source.d | 3 +- 6 files changed, 108 insertions(+), 27 deletions(-) diff --git a/api/source/hip/api/audio/package.d b/api/source/hip/api/audio/package.d index 88ad48501..eb4b9de54 100644 --- a/api/source/hip/api/audio/package.d +++ b/api/source/hip/api/audio/package.d @@ -37,10 +37,25 @@ enum DistanceModel enum HipAudioImplementation { - OPENAL, - OPENSLES, - XAUDIO2, - WEBAUDIO + Null, + OpenAL, + OpenSLES, + XAudio2, + WebAudio, + AVAudioEngine +} + +HipAudioImplementation getAudioImplementationForOS() +{ + with(HipAudioImplementation) + { + version(NullAudio) return Null; + else version(Android) return OpenSLES; + else version(Windows) return XAudio2; + else version(WebAssembly) return WebAudio; + else version(iOS) return AVAudioEngine; + else return OpenAL; + } } version(DirectCall) { public import hip.hipaudio; } diff --git a/build/appleos/HipremeEngine.xcodeproj/project.pbxproj b/build/appleos/HipremeEngine.xcodeproj/project.pbxproj index ad28b965f..d495b3e6e 100644 --- a/build/appleos/HipremeEngine.xcodeproj/project.pbxproj +++ b/build/appleos/HipremeEngine.xcodeproj/project.pbxproj @@ -7,9 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 3130368F29D6807400895DD5 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3130368729D670A400895DD5 /* assets */; }; - 3130369029D6807500895DD5 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3130368729D670A400895DD5 /* assets */; }; - 3130369129D6807500895DD5 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3130368729D670A400895DD5 /* assets */; }; 3130369429D680EB00895DD5 /* Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3156441E29A1546600559889 /* Renderer.m */; }; 3130369529D680EB00895DD5 /* Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3156441E29A1546600559889 /* Renderer.m */; }; 3156442B29A1546900559889 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3156442A29A1546900559889 /* AppDelegate.m */; }; @@ -34,8 +31,14 @@ 31B53C1629D6902C00108E4C /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 31B53C1129D68FC500108E4C /* Metal.framework */; }; 31B53C1729D6902C00108E4C /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 31B53C1029D68FC500108E4C /* MetalKit.framework */; }; EB5383D72AFA7BE700E3B491 /* libdruntime-ldc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EBD5D7C32AF7F89C00494F59 /* libdruntime-ldc.a */; }; - EBAF34EE2B233EF8004B90B1 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBAF34ED2B233EF8004B90B1 /* OpenAL.framework */; }; EBAF34EF2B2395BF004B90B1 /* libhipreme_engine.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EBD5D7D42AFA152200494F59 /* libhipreme_engine.a */; }; + EBAF34F42B240158004B90B1 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3130368729D670A400895DD5 /* assets */; }; + EBAF34F52B240159004B90B1 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3130368729D670A400895DD5 /* assets */; }; + EBAF34F62B24015B004B90B1 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3130368729D670A400895DD5 /* assets */; }; + EBAF34F82B28913B004B90B1 /* AVFAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBAF34F72B28913B004B90B1 /* AVFAudio.framework */; }; + EBAF34FC2B289B5A004B90B1 /* CoreAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBAF34F92B289B59004B90B1 /* CoreAudioKit.framework */; }; + EBAF34FE2B289B5A004B90B1 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBAF34FB2B289B59004B90B1 /* CoreAudio.framework */; }; + EBAF35012B289B6F004B90B1 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBAF34FF2B289B6F004B90B1 /* AudioToolbox.framework */; }; EBD5D7C92AFA13E300494F59 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBD5D7C82AFA13E300494F59 /* Metal.framework */; }; EBD5D7CB2AFA13EA00494F59 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBD5D7CA2AFA13EA00494F59 /* MetalKit.framework */; }; EBD5D7CD2AFA13F000494F59 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBD5D7CC2AFA13F000494F59 /* UIKit.framework */; }; @@ -123,6 +126,12 @@ 31B53C1429D68FD400108E4C /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; EB8B15322B03D0CF001329EC /* modules */ = {isa = PBXFileReference; lastKnownFileType = folder; name = modules; path = ../../modules; sourceTree = SOURCE_ROOT; }; EBAF34ED2B233EF8004B90B1 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; }; + EBAF34F72B28913B004B90B1 /* AVFAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFAudio.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/AVFAudio.framework; sourceTree = DEVELOPER_DIR; }; + EBAF34F92B289B59004B90B1 /* CoreAudioKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/CoreAudioKit.framework; sourceTree = DEVELOPER_DIR; }; + EBAF34FA2B289B59004B90B1 /* CoreAudioTypes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioTypes.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/CoreAudioTypes.framework; sourceTree = DEVELOPER_DIR; }; + EBAF34FB2B289B59004B90B1 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; }; + EBAF34FF2B289B6F004B90B1 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; }; + EBAF35002B289B6F004B90B1 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/AudioUnit.framework; sourceTree = DEVELOPER_DIR; }; EBD5D7C32AF7F89C00494F59 /* libdruntime-ldc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libdruntime-ldc.a"; path = "HipremeEngine_D/static/libdruntime-ldc.a"; sourceTree = ""; }; EBD5D7C82AFA13E300494F59 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; }; EBD5D7CA2AFA13EA00494F59 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -169,8 +178,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + EBAF35012B289B6F004B90B1 /* AudioToolbox.framework in Frameworks */, + EBAF34FC2B289B5A004B90B1 /* CoreAudioKit.framework in Frameworks */, + EBAF34FE2B289B5A004B90B1 /* CoreAudio.framework in Frameworks */, + EBAF34F82B28913B004B90B1 /* AVFAudio.framework in Frameworks */, EBAF34EF2B2395BF004B90B1 /* libhipreme_engine.a in Frameworks */, - EBAF34EE2B233EF8004B90B1 /* OpenAL.framework in Frameworks */, EB5383D72AFA7BE700E3B491 /* libdruntime-ldc.a in Frameworks */, EBD5D7CD2AFA13F000494F59 /* UIKit.framework in Frameworks */, EBD5D7CB2AFA13EA00494F59 /* MetalKit.framework in Frameworks */, @@ -285,6 +297,12 @@ 315796D729B6771F00CE2D39 /* Frameworks */ = { isa = PBXGroup; children = ( + EBAF34FF2B289B6F004B90B1 /* AudioToolbox.framework */, + EBAF35002B289B6F004B90B1 /* AudioUnit.framework */, + EBAF34FB2B289B59004B90B1 /* CoreAudio.framework */, + EBAF34F92B289B59004B90B1 /* CoreAudioKit.framework */, + EBAF34FA2B289B59004B90B1 /* CoreAudioTypes.framework */, + EBAF34F72B28913B004B90B1 /* AVFAudio.framework */, EBAF34ED2B233EF8004B90B1 /* OpenAL.framework */, EBD5D7E92AFA152400494F59 /* libarsd-official_bmp.a */, EBD5D7E22AFA152300494F59 /* libarsd-official_color_base.a */, @@ -477,8 +495,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3130368F29D6807400895DD5 /* assets in Resources */, 3156443129A1546900559889 /* Main.storyboard in Resources */, + EBAF34F52B240159004B90B1 /* assets in Resources */, 3156446329A1546900559889 /* Assets.xcassets in Resources */, 3156443429A1546900559889 /* LaunchScreen.storyboard in Resources */, ); @@ -489,7 +507,7 @@ buildActionMask = 2147483647; files = ( 3156444529A1546900559889 /* Main.storyboard in Resources */, - 3130369029D6807500895DD5 /* assets in Resources */, + EBAF34F42B240158004B90B1 /* assets in Resources */, 3156446429A1546900559889 /* Assets.xcassets in Resources */, 3156444829A1546900559889 /* LaunchScreen.storyboard in Resources */, ); @@ -499,7 +517,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3130369129D6807500895DD5 /* assets in Resources */, + EBAF34F62B24015B004B90B1 /* assets in Resources */, 3156446529A1546900559889 /* Assets.xcassets in Resources */, 3156445929A1546900559889 /* Main.storyboard in Resources */, ); @@ -731,7 +749,6 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-lBindBC_OpenAL", "-larsd-official_bmp", "-larsd-official_color_base", "-larsd-official_core", @@ -745,6 +762,7 @@ "-laudio-formats", "-laudio", "-laudio_decoding", + "-lavaudioengine", "-lbind", "-lconfig", "-lconsole", @@ -759,6 +777,7 @@ "-lmatch3", "-lmath", "-lmetal", + "-lobjc_meta", "-lrenderer", "-ltimer", "-ltween", @@ -804,7 +823,6 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-lBindBC_OpenAL", "-larsd-official_bmp", "-larsd-official_color_base", "-larsd-official_core", @@ -818,6 +836,7 @@ "-laudio-formats", "-laudio", "-laudio_decoding", + "-lavaudioengine", "-lbind", "-lconfig", "-lconsole", @@ -832,6 +851,7 @@ "-lmatch3", "-lmath", "-lmetal", + "-lobjc_meta", "-lrenderer", "-ltimer", "-ltween", @@ -868,7 +888,6 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-lBindBC_OpenAL", "-larsd-official_bmp", "-larsd-official_color_base", "-larsd-official_core", @@ -882,6 +901,7 @@ "-laudio-formats", "-laudio", "-laudio_decoding", + "-lavaudioengine", "-lbind", "-lconfig", "-lconsole", @@ -896,6 +916,7 @@ "-lmatch3", "-lmath", "-lmetal", + "-lobjc_meta", "-lrenderer", "-ltimer", "-ltween", @@ -931,7 +952,6 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-lBindBC_OpenAL", "-larsd-official_bmp", "-larsd-official_color_base", "-larsd-official_core", @@ -945,6 +965,7 @@ "-laudio-formats", "-laudio", "-laudio_decoding", + "-lavaudioengine", "-lbind", "-lconfig", "-lconsole", @@ -959,6 +980,7 @@ "-lmatch3", "-lmath", "-lmetal", + "-lobjc_meta", "-lrenderer", "-ltimer", "-ltween", @@ -1003,7 +1025,6 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-lBindBC_OpenAL", "-larsd-official_bmp", "-larsd-official_color_base", "-larsd-official_core", @@ -1017,6 +1038,7 @@ "-laudio-formats", "-laudio", "-laudio_decoding", + "-lavaudioengine", "-lbind", "-lconfig", "-lconsole", @@ -1031,6 +1053,7 @@ "-lmatch3", "-lmath", "-lmetal", + "-lobjc_meta", "-lrenderer", "-ltimer", "-ltween", @@ -1072,7 +1095,6 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-lBindBC_OpenAL", "-larsd-official_bmp", "-larsd-official_color_base", "-larsd-official_core", @@ -1086,6 +1108,7 @@ "-laudio-formats", "-laudio", "-laudio_decoding", + "-lavaudioengine", "-lbind", "-lconfig", "-lconsole", @@ -1100,6 +1123,7 @@ "-lmatch3", "-lmath", "-lmetal", + "-lobjc_meta", "-lrenderer", "-ltimer", "-ltween", diff --git a/dependencies/avaudioengine b/dependencies/avaudioengine index fd203458d..9466c220a 160000 --- a/dependencies/avaudioengine +++ b/dependencies/avaudioengine @@ -1 +1 @@ -Subproject commit fd203458d91cbd1339aa67455250479b45ea25b1 +Subproject commit 9466c220a4e748484887d7f59236023a212b36a5 diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d b/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d index bf81b6f43..60b59353e 100644 --- a/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/clip.d @@ -12,9 +12,19 @@ import avaudiosourcenode; import avaudioconverter; -extern(C++) void tempDeallocator(const AudioBufferList*) +extern(C) void tempDeallocator(const(AudioBufferList)* bufferList) { + import hip.util.memory; + free(cast(void*)bufferList); +} +AudioBufferList* getAudioBufferList(AudioBuffer buff) +{ + import hip.util.memory; + AudioBufferList* ret = cast(AudioBufferList*)malloc(AudioBufferList.sizeof); + ret.mNumberBuffers = 1; + ret.mBuffers[0] = buff; + return ret; } class HipAVAudioClip : HipAudioClip @@ -26,28 +36,58 @@ class HipAVAudioClip : HipAudioClip this(IHipAudioDecoder decoder, HipAudioClipHint hint) { super(decoder, hint); //TODO: Change num channels - buffer = AVAudioPCMBuffer.alloc.init; } override void setBufferData(HipAudioBuffer* buffer, ubyte[] data, uint size = 0) { if(getHint.needsChannelConversion || getHint.needsDecode || getHint.needsResample) { + import hip.console.log; + import hip.util.conv; + + static void debugFormat(AVAudioFormat f) + { + import hip.console.log; + logln("sampleRate: ", f.sampleRate, " , interleaved: ", f.isInterleaved, " format: ", f.commonFormat ); + } + static void debugBuffer(AVAudioPCMBuffer b) + { + import hip.console.log; + logln("frameLength: ", b.frameLength, " , frameCapacity: ", b.frameCapacity, " stride: ", b.stride); + } + AVAudioFormat rawFormat = HipAVAudioPlayer.fromConfig(decoder.getAudioConfig); converter = AVAudioConverter.alloc.initFromFormat( rawFormat, HipAVAudioPlayer.fromConfig(HipAVAudioPlayer.getAudioConfig) ); - AudioBufferList list = AudioBufferList(1, AudioBuffer(decoder.getClipChannels, + AudioBufferList* list = getAudioBufferList(AudioBuffer(decoder.getClipChannels, cast(uint)getClipSize, getClipData.ptr) ); AVAudioPCMBuffer temp = AVAudioPCMBuffer.alloc.initWithPCMFormat( - rawFormat, &list, &tempDeallocator + rawFormat, list, &tempDeallocator ); + NSError err; - if(!converter.convertToBuffer(this.buffer, temp, &err)) + auto convFn = block((AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus* outStatus) + { + if(temp.frameLength > 0) + { + *outStatus = AVAudioConverterInputStatus._HaveData; + return cast(AVAudioBuffer)temp; + } + else + { + *outStatus = AVAudioConverterInputStatus._NoDataNow; + return null; + } + }); + + converter.convertToBuffer(cast(AVAudioBuffer)buffer.avaudio, &err, &convFn); + + if(err) { import hip.error.handler; ErrorHandler.assertExit(false, "Could not convert buffer: "~err.toString); @@ -69,9 +109,10 @@ class HipAVAudioClip : HipAudioClip ///Nothing to do override protected void onUpdateStream(ubyte[] data, uint decodedSize){} - ///Wraps an XAudio buffer + ///Wraps an AVAudioBuffer buffer override protected HipAudioBufferWrapper createBuffer(ubyte[] data) { + this.buffer = AVAudioPCMBuffer.alloc.initWithPCMFormat(HipAVAudioPlayer.fromConfig(HipAVAudioPlayer.getAudioConfig), cast(uint)data.length); HipAudioBufferWrapper ret; // TODO: implement ret.buffer.avaudio = buffer; return ret; diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/player.d b/modules/audio/source/hip/hipaudio/backend/avaudio/player.d index aad6b6acd..e429f220c 100644 --- a/modules/audio/source/hip/hipaudio/backend/avaudio/player.d +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/player.d @@ -71,7 +71,7 @@ class HipAVAudioPlayer : IHipAudioPlayer public bool play_streamed(AHipAudioSource src){return src.play_streamed();} public AHipAudioSource getSource(bool isStreamed){return new HipAVAudioSource(this);} - public IHipAudioClip getClip(){return new HipAVAudioClip(new HipAudioDecoder(), HipAudioClipHint(2, 44_100, false, true));} + public IHipAudioClip getClip(){return new HipAVAudioClip(new HipAudioDecoder(), HipAudioClipHint(config.channels, config.sampleRate, false, true));} public IHipAudioClip loadStreamed(string audioName, uint chunkSize) { diff --git a/modules/audio/source/hip/hipaudio/backend/avaudio/source.d b/modules/audio/source/hip/hipaudio/backend/avaudio/source.d index 690be4ea4..ca061fcf6 100644 --- a/modules/audio/source/hip/hipaudio/backend/avaudio/source.d +++ b/modules/audio/source/hip/hipaudio/backend/avaudio/source.d @@ -48,7 +48,8 @@ class HipAVAudioSource : HipAudioSource if(isPlaying) { } - player.scheduleBuffer(getBufferFromAPI(clip).avaudio); + AVAudioPCMBuffer b = getBufferFromAPI(clip).avaudio; + player.scheduleBuffer(b); player.play(); return true; } From 1e745ea70ccee264e8faf212800dc480a835862f Mon Sep 17 00:00:00 2001 From: Hipreme Date: Wed, 13 Dec 2023 23:22:57 -0300 Subject: [PATCH 5/5] Fixed: iOS building faster since no need to codesign. Build selector now will clear cache when changing the game. Fixed wrong touch coordinates --- build/appleos/HipremeEngine iOS/InputView.m | 30 +++++++++++-------- .../source/hip/audio_decoding/audio.d | 23 +++++++------- tools/user/build_selector/source/commons.d | 10 +++++++ .../build_selector/source/game_selector.d | 11 +++++-- .../user/build_selector/source/targets/ios.d | 13 ++++++-- 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/build/appleos/HipremeEngine iOS/InputView.m b/build/appleos/HipremeEngine iOS/InputView.m index 2d3792af2..55b00c864 100644 --- a/build/appleos/HipremeEngine iOS/InputView.m +++ b/build/appleos/HipremeEngine iOS/InputView.m @@ -39,47 +39,48 @@ - (BOOL)acceptsFirstResponder - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - NSLog(@"Touches began"); int id_ = 0; + CGFloat scale = [[UIScreen mainScreen] scale]; for(UITouch* touch in touches) { CGPoint xy = [touch locationInView:nil]; - HipInputOnTouchPressed(id_++, xy.x, [self getY:xy.y]); + HipInputOnTouchPressed(id_++, xy.x*scale, [self getY:xy.y*scale]); } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSLog(@"Touches moved"); int id_ = 0; + CGFloat scale = [[UIScreen mainScreen] scale]; for(UITouch* touch in touches) { CGPoint xy = [touch locationInView:nil]; - HipInputOnTouchMoved(id_++, xy.x, [self getY:xy.y]); + HipInputOnTouchMoved(id_++, xy.x*scale, [self getY:xy.y*scale]); } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - NSLog(@"Touches ended"); int id_ = 0; + CGFloat scale = [[UIScreen mainScreen] scale]; for(UITouch* touch in touches) { CGPoint xy = [touch locationInView:nil]; - HipInputOnTouchReleased(id_++, xy.x, [self getY:xy.y]); + HipInputOnTouchReleased(id_++, xy.x*scale, [self getY:xy.y*scale]); } } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - NSLog(@"Touches cancelled"); int id_ = 0; + CGFloat scale = [[UIScreen mainScreen] scale]; + for(UITouch* touch in touches) { CGPoint xy = [touch locationInView:nil]; - HipInputOnTouchReleased(id_++, xy.x, [self getY:xy.y]); + HipInputOnTouchReleased(id_++, xy.x*scale, [self getY:xy.y*scale]); } } @@ -96,9 +97,10 @@ -(float) getY:(int) y void hipSetMTKView(void** MTKView, int* outWidth, int* outHeight) { *MTKView = (__bridge void*)mtkView; + CGFloat scale = [[UIScreen mainScreen] scale]; CGSize sz = mtkView.frame.size; - *outWidth = (int)sz.width; - *outHeight = (int)sz.height; + *outWidth = (int)sz.width*scale; + *outHeight = (int)sz.height*scale; } typedef struct @@ -109,15 +111,17 @@ void hipSetMTKView(void** MTKView, int* outWidth, int* outHeight) HipWindowSize hipGetWindowSize(void) { HipWindowSize ret; - ret.width = (int)mtkView.frame.size.width; - ret.height = (int)mtkView.frame.size.height; + CGFloat scale = [[UIScreen mainScreen] scale]; + ret.width = (int)mtkView.frame.size.width*scale; + ret.height = (int)mtkView.frame.size.height*scale; return ret; } void hipSetWindowSize(unsigned int width, unsigned int height) { CGRect frame = mtkView.frame; - frame.size = CGSizeMake((CGFloat)width, (CGFloat)height); + CGFloat scale = [[UIScreen mainScreen] scale]; + frame.size = CGSizeMake((CGFloat)width*scale, (CGFloat)height*scale); mainInputView.frame = mtkView.frame = frame; } diff --git a/modules/audio_decoding/source/hip/audio_decoding/audio.d b/modules/audio_decoding/source/hip/audio_decoding/audio.d index dc02c6934..fb8ac7230 100644 --- a/modules/audio_decoding/source/hip/audio_decoding/audio.d +++ b/modules/audio_decoding/source/hip/audio_decoding/audio.d @@ -4,17 +4,17 @@ public import hip.api.data.audio; -private char* getNameFromEncoding(HipAudioEncoding encoding) +private const(char)* getNameFromEncoding(HipAudioEncoding encoding) { - final switch(encoding) + final switch(encoding) with(HipAudioEncoding) { - case HipAudioEncoding.MOD: return cast(char*)"mod\0".ptr; - case HipAudioEncoding.XM: return cast(char*)"xm\0".ptr; - case HipAudioEncoding.FLAC:return cast(char*)"flac\0".ptr; - case HipAudioEncoding.MIDI:return cast(char*)"midi\0".ptr; - case HipAudioEncoding.MP3:return cast(char*)"mp3\0".ptr; - case HipAudioEncoding.OGG:return cast(char*)"ogg\0".ptr; - case HipAudioEncoding.WAV:return cast(char*)"wav\0".ptr; + case MOD: return "mod"; + case XM: return "xm"; + case FLAC:return "flac"; + case MIDI:return "midi"; + case MP3:return "mp3"; + case OGG:return "ogg"; + case WAV:return "wav"; } } @@ -70,7 +70,7 @@ private abstract class AHipAudioDecoder : IHipAudioDecoder size_t getClipSize(){return clipSize;} float getDuration(){return duration;} uint getSamplerate(){return cast(uint)sampleRate;} - AudioConfig getAudioConfig(){return AudioConfig.init;} + AudioConfig getAudioConfig(){return AudioConfig(getSamplerate, AudioFormat.init, getClipChannels, cast(int)getClipSize);} bool resample(in ubyte[] data, HipAudioType type, uint outputSampleRate, uint outputChannels){return false;} bool channelConversion(in ubyte[] data, ubyte from, ubyte to){return false;} } @@ -222,6 +222,9 @@ version(AudioFormatsDecoder) return currentRead; } + override AudioConfig getAudioConfig(){return AudioConfig(getSamplerate, AudioFormat.float32Little, getClipChannels, cast(int)getClipSize);} + + void dispose(){input.cleanUp();} override bool resample(in ubyte[] data, HipAudioType type, uint outputSampleRate, uint outputChannels, diff --git a/tools/user/build_selector/source/commons.d b/tools/user/build_selector/source/commons.d index b95da008f..98138baf1 100644 --- a/tools/user/build_selector/source/commons.d +++ b/tools/user/build_selector/source/commons.d @@ -428,6 +428,16 @@ void cached(scope void delegate() dg, string f = __FILE__, size_t l = __LINE__) } } +/** + * Clears all cache. + * This may be useful after a dub.template.json was already generated. + * Or for example, after changing the current game. + */ +void clearCache() +{ + session.cache.clear; +} + bool pollForExecutionPermission(ref Terminal t, ref RealTimeConsoleInput input, string operation) { t.writelnHighlighted(operation~" [Y]es/[N]o"); diff --git a/tools/user/build_selector/source/game_selector.d b/tools/user/build_selector/source/game_selector.d index bd0419d37..52cca0d30 100644 --- a/tools/user/build_selector/source/game_selector.d +++ b/tools/user/build_selector/source/game_selector.d @@ -24,12 +24,18 @@ private ChoiceResult typeGamePath(Choice* self, ref Terminal t, ref RealTimeCons } t.writelnSuccess("Selected game path '", gamePath, "'"); - configs["gamePath"] = gamePath; + changeGamePath(gamePath); hasTypedGamepath = true; return ChoiceResult.Continue; } +private void changeGamePath(string newGamePath) +{ + configs["gamePath"] = newGamePath; + clearCache(); +} + ChoiceResult selectGameFolder(Choice* c, ref Terminal t, ref RealTimeConsoleInput input, in CompilationOptions cOpts) { Choice* selectedChoice = selectInFolderExtra( @@ -42,8 +48,9 @@ ChoiceResult selectGameFolder(Choice* c, ref Terminal t, ref RealTimeConsoleInpu ); if(selectedChoice.onSelected != null) selectedChoice.onSelected(selectedChoice, t, input, cOpts); + // Chose a path if(selectedChoice.onSelected == null) - configs["gamePath"] = selectedChoice.name; + changeGamePath(selectedChoice.name); if(hasTypedGamepath || selectedChoice.onSelected == null) { configs["selectedChoice"] = 0; diff --git a/tools/user/build_selector/source/targets/ios.d b/tools/user/build_selector/source/targets/ios.d index 045e3c943..42b17b901 100644 --- a/tools/user/build_selector/source/targets/ios.d +++ b/tools/user/build_selector/source/targets/ios.d @@ -3,16 +3,24 @@ import common_macos; import commons; import global_opts; + +enum TARGET_TYPE = "simulator"; enum iosArch = [ "simulator" : "x86_64", "hardware" : "arm64" ]; +string getExtraCommand(string type) +{ + if(type == "simulator") return " -sdk iphonesimulator "; + return ""; +} + ChoiceResult prepareiOS(Choice* c, ref Terminal t, ref RealTimeConsoleInput input, in CompilationOptions cOpts) { string buildTarget = getBuildTarget("ios"); - string arch = iosArch["simulator"]; + string arch = iosArch[TARGET_TYPE]; prepareAppleOSBase(c,t,input); string out_extraLinkerFlags; @@ -30,6 +38,7 @@ ChoiceResult prepareiOS(Choice* c, ref Terminal t, ref RealTimeConsoleInput inpu cached(() => timed(() => outputTemplateForTarget(t, buildTarget))); string codeSignCommand = getCodeSignCommand(t); + string extraCommands = getExtraCommand(TARGET_TYPE); with(WorkingDir(getHipPath)) { @@ -56,7 +65,7 @@ ChoiceResult prepareiOS(Choice* c, ref Terminal t, ref RealTimeConsoleInput inpu "xcodebuild -jobs 8 -configuration Debug -scheme 'HipremeEngine iOS' " ~ clean ~ "build CONFIGURATION_BUILD_DIR=\"bin\" "~ - codeSignCommand ~ + codeSignCommand ~ extraCommands ~ "-destination 'platform=iOS Simulator,name=iPhone 14,OS=16.2' " ~ " && cd bin && HipremeEngine.app/Contents/iOS/HipremeEngine") );