Advertisement
Guest User

Untitled

a guest
Apr 5th, 2023
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.33 KB | Gaming | 0 0
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using AOT;
  4. using FMOD;
  5. using FMOD.Studio;
  6. using FMODUnity;
  7. using UnityEngine;
  8.  
  9. public static class AudioClipToFmod
  10. {
  11.     private static EVENT_CALLBACK dialogueCallback;
  12.  
  13.     public static EventInstance Play(AudioClip audioclip)
  14.     {
  15.         float[] audioclip_data = new float[audioclip.samples * audioclip.channels];
  16.         audioclip.GetData(audioclip_data, 0);
  17.  
  18.         SoundRequirements sound_requirements = new SoundRequirements(
  19.             audioclip.name,
  20.             audioclip.samples,
  21.             audioclip.channels,
  22.             audioclip.frequency,
  23.             audioclip_data);
  24.        
  25.         var audioClipInstance = RuntimeManager.CreateInstance("event:/App/WalkieTalkie");
  26.        
  27.         GCHandle stringHandle = GCHandle.Alloc(sound_requirements);
  28.         audioClipInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
  29.        
  30.         dialogueCallback ??= PlayFileCallBackUsingAudioFile;
  31.        
  32.         audioClipInstance.setCallback(dialogueCallback);
  33.         audioClipInstance.start();
  34.         audioClipInstance.release();
  35.  
  36.         return audioClipInstance;
  37.     }
  38.  
  39.     [MonoPInvokeCallback(typeof(EVENT_CALLBACK))]
  40.     private static RESULT PlayFileCallBackUsingAudioFile(EVENT_CALLBACK_TYPE type, IntPtr instPrt, IntPtr paramsPrt)
  41.     {
  42.         EventInstance inst = new EventInstance(instPrt);
  43.  
  44.         if (!inst.isValid())
  45.         {
  46.             return RESULT.ERR_EVENT_NOTFOUND;
  47.         }
  48.        
  49.         inst.getUserData(out IntPtr clipDataPtr);
  50.         GCHandle clipHandle = GCHandle.FromIntPtr(clipDataPtr);
  51.  
  52.         if (clipHandle.Target is SoundRequirements clip)
  53.         {
  54.             switch (type)
  55.             {
  56.                 case EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
  57.                 {
  58.                    
  59.                     var param = (PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(paramsPrt, typeof(PROGRAMMER_SOUND_PROPERTIES));
  60.                    
  61.                     ERRCHECK(RuntimeManager.CoreSystem.getMasterChannelGroup(out ChannelGroup masterGroup), "Failed to get masterGroup from core system");
  62.                    
  63.                     uint lenBytes = (uint)(clip.samples * clip.channels * sizeof(float));
  64.                    
  65.                     CREATESOUNDEXINFO soundInfo = new CREATESOUNDEXINFO
  66.                     {
  67.                         cbsize = Marshal.SizeOf(typeof(CREATESOUNDEXINFO)),
  68.                         length = lenBytes,
  69.                         format = SOUND_FORMAT.PCMFLOAT,
  70.                         defaultfrequency = clip.defaultFrequency,
  71.                         numchannels = clip.channels
  72.                     };
  73.  
  74.                     RESULT result = ERRCHECK(RuntimeManager.CoreSystem.createSound(clip.name, MODE.OPENUSER, ref soundInfo, out Sound sound), "Failed to create sound");
  75.                     if (result != RESULT.OK)
  76.                         return result;
  77.                    
  78.                     result = ERRCHECK(sound.@lock(0, lenBytes, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2), "Failed to lock sound");
  79.                     if (result != RESULT.OK)
  80.                         return result;
  81.  
  82.                     Marshal.Copy(clip.sampleData, 0, ptr1, (int)(len1 / sizeof(float)));
  83.                     if (len2 > 0)
  84.                         Marshal.Copy(clip.sampleData, (int)(len1 / sizeof(float)), ptr2, (int)(len2 / sizeof(float)));
  85.  
  86.                     result = ERRCHECK(sound.unlock(ptr1, ptr2, len1, len2), "Failed to unlock sound");
  87.                     if (result != RESULT.OK)
  88.                         return result;
  89.  
  90.                     ERRCHECK(sound.setMode(MODE.DEFAULT), "Failed to set the sound mode");
  91.  
  92.  
  93.                     param.sound = sound.handle;
  94.                     param.subsoundIndex = -1;
  95.                    
  96.                     Marshal.StructureToPtr(param, paramsPrt, false);
  97.                 }
  98.                    
  99.                     break;
  100.                
  101.                 case EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
  102.                 {
  103.                     var param = (PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(paramsPrt, typeof(PROGRAMMER_SOUND_PROPERTIES));
  104.                     var sound = new Sound(param.sound);
  105.                     RESULT result = ERRCHECK(sound.release(), "Failed to release sound");
  106.                     if (result != RESULT.OK)
  107.                         return result;
  108.                 }
  109.                     break;
  110.                 case EVENT_CALLBACK_TYPE.DESTROYED:
  111.                     clipHandle.Free();
  112.                     break;
  113.             }
  114.         }
  115.        
  116.         return RESULT.OK;
  117.     }
  118.    
  119.     private static RESULT ERRCHECK(RESULT result, string failMsg)
  120.     {
  121. #if UNITY_EDITOR
  122.         if (result != RESULT.OK)
  123.         {
  124.             UnityEngine.Debug.Log(failMsg + " with result: " + result);
  125.             return result;
  126.         }
  127. #endif
  128.         return result;
  129.     }
  130. }
  131.  
  132. internal class SoundRequirements
  133. {
  134.     public readonly string name;
  135.     public readonly int samples;
  136.     public readonly int channels;
  137.     public readonly int defaultFrequency;
  138.     public readonly float[] sampleData;
  139.    
  140.     public SoundRequirements(string name, int samples, int channel, int defaultFrequency, float[] sampleData)
  141.     {
  142.         this.name = name;
  143.         this.samples = samples;
  144.         channels = channel;
  145.         this.defaultFrequency = defaultFrequency;
  146.         this.sampleData = sampleData;
  147.     }
  148. }
Tags: C# fmod
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement