Thanks to your steady support, I’ve made a great progress on my work.
However, there’s one critical blocker.
Due to the nature of my project, there’s a case I have to play multiple samples multiple times simultaneously.
I’ve set up my scene like in the screenshot below, and the name of game objects are identical to their attached components:
But if I rapidly and repeatedly press Z and X key to invoke the playback of the samples (more like fifty to hundred times), Unity crashes at some point and leaves this kind of stacktraces in the Editor log file:
========== OUTPUTTING STACK TRACE ==================
0x00007FFD6EC88A3C (fmodstudioL) FMOD::ChannelControl::stop
0x00007FFD6ED60920 (fmodstudioL) FMOD_System_Update
0x00007FFD6ED60179 (fmodstudioL) FMOD_System_Update
0x00007FFD6ED99B5D (fmodstudioL) FMOD::SystemI::createMemoryFile
0x00007FFD6ED9A2D9 (fmodstudioL) FMOD::SystemI::createMemoryFile
0x00007FFD6ED3A48A (fmodstudioL) FMOD::System::update
SymInit: Symbol-SearchPath: 'C:/Program Files/Unity/Hub/Editor/6000.0.45f1/Editor/Data/Mono;
They definitely look like FMOD DLLs’ native-level internal errors, which make me difficult to dig into any further.
- What should I do to run my program stably, without the crash?
- This question is optional, but is there a way to create certain channels and limit playbacks within the range? I tried adding a channel group to the master channel but I’m not sure if it’s the right way.
Code for:
<DirectSoundManager.cs>
using UnityEngine;
public class DirectSoundManager : MonoBehaviour
{
public DirectSoundPlayer soundPlayer;
public void PlayDownloadedSound()
{
const string filePath = @"C:\path_to_sample\sample1.wav";
soundPlayer.PlayAudioSegment(filePath, 700, 900);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
const string filePath = @"C:\path_to_sample\sample2.wav";
soundPlayer.PlayAudioSegment(filePath, 5000, 6000);
}
else if (Input.GetKeyDown(KeyCode.X))
{
const string filePath = @"C:\path_to_sample\sample3.wav";
soundPlayer.PlayAudioSegment(filePath, 20000, 22000);
}
}
private void OnDestroy()
{
FMODUnity.RuntimeManager.CoreSystem.release();
}
}
And here’s the code for:
<DirectSoundPlayer.cs>
using UnityEngine;
using FMOD;
using FMODUnity;
using System;
using System.Collections.Generic;
public class DirectSoundPlayer : MonoBehaviour
{
private FMOD.System coreSystem;
private ChannelGroup masterGroup;
private uint syncPointIndex;
private Dictionary<string, Sound> _sounds = new();
private void Start()
{
coreSystem = RuntimeManager.CoreSystem;
coreSystem.getMasterChannelGroup(out masterGroup);
}
public void PlayAudioSegment(string filePath, uint startPos, uint endPos, float pitch = 1.0f)
{
Sound sound;
if (_sounds.ContainsKey(filePath))
sound = _sounds[filePath];
else
{
coreSystem.createSound(filePath, MODE.DEFAULT, out sound);
_sounds[filePath] = sound;
}
var hasPoint = false;
sound.getNumSyncPoints(out var count);
for (int i = 0; i < count; i++)
{
sound.getSyncPoint(i, out var point);
sound.getSyncPointInfo(point, out _, 100, out var offset, TIMEUNIT.MS);
if (offset == endPos)
{
hasPoint = true;
break;
}
}
if (!hasPoint)
{
sound.addSyncPoint(endPos, TIMEUNIT.MS, endPos.ToString(), out var syncPoint);
}
coreSystem.playSound(sound, masterGroup, true, out var channel);
channel.setPosition(startPos, TIMEUNIT.MS);
channel.setCallback(ChannelStopCallback);
channel.setPaused(false);
}
RESULT ChannelStopCallback(IntPtr channelcontrol, CHANNELCONTROL_TYPE controltype,
CHANNELCONTROL_CALLBACK_TYPE callbacktype, IntPtr commanddata1, IntPtr commanddata2)
{
if (callbacktype == CHANNELCONTROL_CALLBACK_TYPE.SYNCPOINT)
{
var channel = new Channel(channelcontrol);
channel.setVolume(0f);
}
return RESULT.OK;
}
}