- Home /
AudioClip generated by an external process and loaded into the editor has no samples
I'm working on a custom ScriptedImporter
-- let's call it LmmsImporter
-- that loads project files from the LMMS sequencer as AudioClip
s. I don't parse the project file; instead, I expect users to install LMMS, configure its location, then store their project files inside their Assets
directory. After the asset settings are configured, the import process looks like this:
Create command-line arguments based on the properties offered by
LmmsImporter
Get a temporary path inside the project's
Temp
directory (not the OS's equivalent)Spawn an LMMS process that renders the imported project file to the path given by (2), with the arguments given by (1).
Wait for the process to complete.
Load the
AudioClip
at "runtime" (i.e. in an editor script, not as an imported asset) with `UnityWebRequestMultimedia.GetAudioClip`Clone the
AudioClip
.Set the cloned
AudioClip
to be the LMMS project asset's main object, as described here.Save the imported asset, then delete the original audio file generated by (3).
Everything up to but not including step 7 works as expected. In fact, even step 7 appears to work as expected. But when I open up the imported AudioClip
, it has no samples. When I try to play the preview in the editor, I get this error in the editor console:
Error: Cannot create FMOD::Sound instance for resource , (Error loading file. ) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
What makes this weird is that:
The sound is properly rendered by LMMS and saved to the filesystem. Nothing unusual happens here.
Playing the
AudioClip
inside the importer script immediately after it's loaded (i.e. while still inOnImportAsset
) with `AudioSource.PlayAtPoint` works as expected.The data is properly cloned; I checked, the arrays are equal.
I do not receive any errors or exceptions except those that I've already described, not even from LMMS.
This is an excerpt of my code with the parts I think are most relevant:
using System; using System.Diagnostics; using System.IO; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using UnityEditor; using UnityEditor.Experimental.AssetImporters;
[ScriptedImporter(1, new[] { "mmp", "mmpz" })] public class LmmsImporter : ScriptedImporter { // Properties omitted for brevity
public override void OnImportAsset(AssetImportContext ctx)
{
var relativeTempPath = FileUtil.GetUniqueTempPathInProject();
var projectDir = Path.GetDirectoryName(Application.dataPath);
var absoluteAssetPath = Path.Combine(projectDir, assetPath);
var tempPath = Path.Combine(projectDir, relativeTempPath);
try
{
using (Process lmms = new Process())
{
// Process invocation details and error handling omitted for brevity
// ...one successfully rendered WAV, OGG, or MP3 file later...
using (var request = UnityWebRequestMultimedia.GetAudioClip(new Uri(tempPath), audioFormat))
{
var handler = request.downloadHandler as DownloadHandlerAudioClip;
handler.compressed = false;
handler.streamAudio = false;
request.timeout = LOAD_MEDIA_TIMEOUT;
var operation = request.SendWebRequest();
while (!(request.isHttpError || request.isNetworkError || handler.isDone)) ;
// Let the request finish, unless we get an error (possibly including a timeout)
var clip = DownloadHandlerAudioClip.GetContent(request);
clip.LoadAudioData();
var assetName = Path.GetFileNameWithoutExtension(assetPath);
var clone = AudioClip.Create("Clip", clip.samples, clip.channels, clip.frequency, false);
using (var so = new SerializedObject(clone))
{
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
clone.SetData(samples, 0);
// Everything above this line works fine
ctx.AddObjectToAsset("AudioClip", clone);
ctx.SetMainObject(clone);
so.ApplyModifiedProperties();
EditorUtility.SetDirty(clone);
}
}
}
}
catch (Exception e)
{
ctx.LogImportError($"Failed import with {e.GetType()}: {e.Message}");
}
}
private const int LOAD_MEDIA_TIMEOUT = 5; // seconds
}
I'm using Unity 2019.1.7f1 Personal, on Ubuntu 19.04. Is this a bug, or am I doing something wrong?
Your answer
Follow this Question
Related Questions
Connecting oracle with unity tutorial, Steps or a way? 1 Answer
Adding an element to List a .asset file of ScriptableObject 0 Answers
How to : Editor.OnPreviewGUI Implementation 0 Answers
asset wont accept attached script 0 Answers
SerializedProperty.animationCurveValue cannot be set directly 1 Answer