Using NAudio to create AudioClip in Unity, freezes 1-2 seconds while reading data





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I am currently using the below code in my Unity project to stream mp3 files from a directory. It works great however, it freezes while the file is read in and the float is filled.
As this project is in VR the freezes are very jarring. How can I resolve it so that it can read in without the lockup? Do I try and put it on another thread?



When commenting out the below lines there are no hitches.



aud = new AudioFileReader(musicPath);



aud.Read(AudioData, 0, (int)aud.Length);



    public void LoadSong(string musicPath){

//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if(songTitle != currentlyPlaying && songTitle != lastPlayedTitle){
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if(craftClip.isReadyToPlay){
playMusic(craftClip, songTitle);
aud.Dispose();
}

}

else
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
}

}


I have also tried to download the file as mentioned in this question https://answers.unity.com/questions/933090/wwwgetaudioclip-streaming-of-mp3-on-this-plattform.html using the below code and I receive the Streaming of 'mp3' on this platform is not supported error despite including the file type. Here is the code I used.



public class AudioDownloadTest : MonoBehaviour {
public AudioSource playThis;
public AudioClip clipy;
string pathh = @"D:TestFilesIntheAirTonightShort.mp3";

IEnumerator Download(string pathh){
WWW song = new WWW(pathh);
yield return song;
clipy = song.GetAudioClip(false,false,AudioType.MPEG);
playThis.clip = clipy;
}

void Start () {
StartCoroutine(Download(pathh));
}


}



I have managed to improve the situation slightly by storing the last played song so that if the user selects the previous song that was played there is no delay.



Many thanks










share|improve this question

























  • Can you comment out the code from aud.Read(AudioData, 0, (int)aud.Length) and below to see if the problem is actually there?

    – Programmer
    Nov 23 '18 at 12:17











  • Could have sworn I had already done that but maybe not :/ It still occurs but for a smaller amount of time, apologies let me take another look.

    – JamieD
    Nov 23 '18 at 12:27













  • currentSong.isDone is bot being used properly. Your LoadSong function should be a coroutine function and you should put in the isDone loop and call the function with StartCoroutine. See the duplicate for more example.

    – Programmer
    Nov 23 '18 at 12:34











  • Removing the WWW related code still causes the issue, it is not required for functionality as the path to the audio file is passed directly to AudioFileReader. I will change my question to feature code without the WWW usage.

    – JamieD
    Nov 23 '18 at 12:39













  • When the new AudioFileReader is created there is a hitch and then it is lengthened when the file is read. It will vary dependent on the size of the audio file but the hitches definitely occur at those points.

    – JamieD
    Nov 23 '18 at 12:48


















1















I am currently using the below code in my Unity project to stream mp3 files from a directory. It works great however, it freezes while the file is read in and the float is filled.
As this project is in VR the freezes are very jarring. How can I resolve it so that it can read in without the lockup? Do I try and put it on another thread?



When commenting out the below lines there are no hitches.



aud = new AudioFileReader(musicPath);



aud.Read(AudioData, 0, (int)aud.Length);



    public void LoadSong(string musicPath){

//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if(songTitle != currentlyPlaying && songTitle != lastPlayedTitle){
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if(craftClip.isReadyToPlay){
playMusic(craftClip, songTitle);
aud.Dispose();
}

}

else
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
}

}


I have also tried to download the file as mentioned in this question https://answers.unity.com/questions/933090/wwwgetaudioclip-streaming-of-mp3-on-this-plattform.html using the below code and I receive the Streaming of 'mp3' on this platform is not supported error despite including the file type. Here is the code I used.



public class AudioDownloadTest : MonoBehaviour {
public AudioSource playThis;
public AudioClip clipy;
string pathh = @"D:TestFilesIntheAirTonightShort.mp3";

IEnumerator Download(string pathh){
WWW song = new WWW(pathh);
yield return song;
clipy = song.GetAudioClip(false,false,AudioType.MPEG);
playThis.clip = clipy;
}

void Start () {
StartCoroutine(Download(pathh));
}


}



I have managed to improve the situation slightly by storing the last played song so that if the user selects the previous song that was played there is no delay.



Many thanks










share|improve this question

























  • Can you comment out the code from aud.Read(AudioData, 0, (int)aud.Length) and below to see if the problem is actually there?

    – Programmer
    Nov 23 '18 at 12:17











  • Could have sworn I had already done that but maybe not :/ It still occurs but for a smaller amount of time, apologies let me take another look.

    – JamieD
    Nov 23 '18 at 12:27













  • currentSong.isDone is bot being used properly. Your LoadSong function should be a coroutine function and you should put in the isDone loop and call the function with StartCoroutine. See the duplicate for more example.

    – Programmer
    Nov 23 '18 at 12:34











  • Removing the WWW related code still causes the issue, it is not required for functionality as the path to the audio file is passed directly to AudioFileReader. I will change my question to feature code without the WWW usage.

    – JamieD
    Nov 23 '18 at 12:39













  • When the new AudioFileReader is created there is a hitch and then it is lengthened when the file is read. It will vary dependent on the size of the audio file but the hitches definitely occur at those points.

    – JamieD
    Nov 23 '18 at 12:48














1












1








1








I am currently using the below code in my Unity project to stream mp3 files from a directory. It works great however, it freezes while the file is read in and the float is filled.
As this project is in VR the freezes are very jarring. How can I resolve it so that it can read in without the lockup? Do I try and put it on another thread?



When commenting out the below lines there are no hitches.



aud = new AudioFileReader(musicPath);



aud.Read(AudioData, 0, (int)aud.Length);



    public void LoadSong(string musicPath){

//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if(songTitle != currentlyPlaying && songTitle != lastPlayedTitle){
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if(craftClip.isReadyToPlay){
playMusic(craftClip, songTitle);
aud.Dispose();
}

}

else
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
}

}


I have also tried to download the file as mentioned in this question https://answers.unity.com/questions/933090/wwwgetaudioclip-streaming-of-mp3-on-this-plattform.html using the below code and I receive the Streaming of 'mp3' on this platform is not supported error despite including the file type. Here is the code I used.



public class AudioDownloadTest : MonoBehaviour {
public AudioSource playThis;
public AudioClip clipy;
string pathh = @"D:TestFilesIntheAirTonightShort.mp3";

IEnumerator Download(string pathh){
WWW song = new WWW(pathh);
yield return song;
clipy = song.GetAudioClip(false,false,AudioType.MPEG);
playThis.clip = clipy;
}

void Start () {
StartCoroutine(Download(pathh));
}


}



I have managed to improve the situation slightly by storing the last played song so that if the user selects the previous song that was played there is no delay.



Many thanks










share|improve this question
















I am currently using the below code in my Unity project to stream mp3 files from a directory. It works great however, it freezes while the file is read in and the float is filled.
As this project is in VR the freezes are very jarring. How can I resolve it so that it can read in without the lockup? Do I try and put it on another thread?



When commenting out the below lines there are no hitches.



aud = new AudioFileReader(musicPath);



aud.Read(AudioData, 0, (int)aud.Length);



    public void LoadSong(string musicPath){

//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if(songTitle != currentlyPlaying && songTitle != lastPlayedTitle){
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if(craftClip.isReadyToPlay){
playMusic(craftClip, songTitle);
aud.Dispose();
}

}

else
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
}

}


I have also tried to download the file as mentioned in this question https://answers.unity.com/questions/933090/wwwgetaudioclip-streaming-of-mp3-on-this-plattform.html using the below code and I receive the Streaming of 'mp3' on this platform is not supported error despite including the file type. Here is the code I used.



public class AudioDownloadTest : MonoBehaviour {
public AudioSource playThis;
public AudioClip clipy;
string pathh = @"D:TestFilesIntheAirTonightShort.mp3";

IEnumerator Download(string pathh){
WWW song = new WWW(pathh);
yield return song;
clipy = song.GetAudioClip(false,false,AudioType.MPEG);
playThis.clip = clipy;
}

void Start () {
StartCoroutine(Download(pathh));
}


}



I have managed to improve the situation slightly by storing the last played song so that if the user selects the previous song that was played there is no delay.



Many thanks







c# unity3d audio naudio






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 4:14







JamieD

















asked Nov 23 '18 at 12:14









JamieDJamieD

84




84













  • Can you comment out the code from aud.Read(AudioData, 0, (int)aud.Length) and below to see if the problem is actually there?

    – Programmer
    Nov 23 '18 at 12:17











  • Could have sworn I had already done that but maybe not :/ It still occurs but for a smaller amount of time, apologies let me take another look.

    – JamieD
    Nov 23 '18 at 12:27













  • currentSong.isDone is bot being used properly. Your LoadSong function should be a coroutine function and you should put in the isDone loop and call the function with StartCoroutine. See the duplicate for more example.

    – Programmer
    Nov 23 '18 at 12:34











  • Removing the WWW related code still causes the issue, it is not required for functionality as the path to the audio file is passed directly to AudioFileReader. I will change my question to feature code without the WWW usage.

    – JamieD
    Nov 23 '18 at 12:39













  • When the new AudioFileReader is created there is a hitch and then it is lengthened when the file is read. It will vary dependent on the size of the audio file but the hitches definitely occur at those points.

    – JamieD
    Nov 23 '18 at 12:48



















  • Can you comment out the code from aud.Read(AudioData, 0, (int)aud.Length) and below to see if the problem is actually there?

    – Programmer
    Nov 23 '18 at 12:17











  • Could have sworn I had already done that but maybe not :/ It still occurs but for a smaller amount of time, apologies let me take another look.

    – JamieD
    Nov 23 '18 at 12:27













  • currentSong.isDone is bot being used properly. Your LoadSong function should be a coroutine function and you should put in the isDone loop and call the function with StartCoroutine. See the duplicate for more example.

    – Programmer
    Nov 23 '18 at 12:34











  • Removing the WWW related code still causes the issue, it is not required for functionality as the path to the audio file is passed directly to AudioFileReader. I will change my question to feature code without the WWW usage.

    – JamieD
    Nov 23 '18 at 12:39













  • When the new AudioFileReader is created there is a hitch and then it is lengthened when the file is read. It will vary dependent on the size of the audio file but the hitches definitely occur at those points.

    – JamieD
    Nov 23 '18 at 12:48

















Can you comment out the code from aud.Read(AudioData, 0, (int)aud.Length) and below to see if the problem is actually there?

– Programmer
Nov 23 '18 at 12:17





Can you comment out the code from aud.Read(AudioData, 0, (int)aud.Length) and below to see if the problem is actually there?

– Programmer
Nov 23 '18 at 12:17













Could have sworn I had already done that but maybe not :/ It still occurs but for a smaller amount of time, apologies let me take another look.

– JamieD
Nov 23 '18 at 12:27







Could have sworn I had already done that but maybe not :/ It still occurs but for a smaller amount of time, apologies let me take another look.

– JamieD
Nov 23 '18 at 12:27















currentSong.isDone is bot being used properly. Your LoadSong function should be a coroutine function and you should put in the isDone loop and call the function with StartCoroutine. See the duplicate for more example.

– Programmer
Nov 23 '18 at 12:34





currentSong.isDone is bot being used properly. Your LoadSong function should be a coroutine function and you should put in the isDone loop and call the function with StartCoroutine. See the duplicate for more example.

– Programmer
Nov 23 '18 at 12:34













Removing the WWW related code still causes the issue, it is not required for functionality as the path to the audio file is passed directly to AudioFileReader. I will change my question to feature code without the WWW usage.

– JamieD
Nov 23 '18 at 12:39







Removing the WWW related code still causes the issue, it is not required for functionality as the path to the audio file is passed directly to AudioFileReader. I will change my question to feature code without the WWW usage.

– JamieD
Nov 23 '18 at 12:39















When the new AudioFileReader is created there is a hitch and then it is lengthened when the file is read. It will vary dependent on the size of the audio file but the hitches definitely occur at those points.

– JamieD
Nov 23 '18 at 12:48





When the new AudioFileReader is created there is a hitch and then it is lengthened when the file is read. It will vary dependent on the size of the audio file but the hitches definitely occur at those points.

– JamieD
Nov 23 '18 at 12:48












1 Answer
1






active

oldest

votes


















0














Audio is usually loaded with the WWW.GetAudioClip function but since you ran into exceptions with it, you decided to use NAudio. The freezing that happens when AudioFileReader(musicPath) and aud.Read(AudioData, 0, (int)aud.Length) executes makes sense since this constructor and function are trying to load an audio file on the main thread and creating a PCM data with them.



Because AudioFileReader is not a Unity API, you should be able to use it in from Thread. Once you're doing reading the audio's float data from another Thread, you can then do a callback to the main Thread to create AudioClip with the AudioClip.Create function since you can't use this API from the main Thread.



Grab UnityThread that enables easy callback on the main thread from this post then see below for what your new LoadSong function should look like. I used ThreadPool but you can use any other Thread API in C# if you wish.



void Awake()
{
//Enable Callback on the main Thread
UnityThread.initUnityThread();
}

public void LoadSong(string musicPath)
{
ThreadPool.QueueUserWorkItem(delegate
{
//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if (songTitle != currentlyPlaying && songTitle != lastPlayedTitle)
{
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Now, create the clip on the main Thread and also play it
UnityThread.executeInUpdate(() =>
{
//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if (craftClip.isReadyToPlay)
{
playMusic(craftClip, songTitle);

/*Disposing on main thread may also introduce freezing so do that in a Thread too*/
ThreadPool.QueueUserWorkItem(delegate { aud.Dispose(); });
}
});
}
else
{
UnityThread.executeInUpdate(() =>
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
});
}
});
}





share|improve this answer



















  • 1





    Thank you so much! It is now only a tiny blip which is acceptable.

    – JamieD
    Nov 25 '18 at 6:32












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446540%2fusing-naudio-to-create-audioclip-in-unity-freezes-1-2-seconds-while-reading-dat%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Audio is usually loaded with the WWW.GetAudioClip function but since you ran into exceptions with it, you decided to use NAudio. The freezing that happens when AudioFileReader(musicPath) and aud.Read(AudioData, 0, (int)aud.Length) executes makes sense since this constructor and function are trying to load an audio file on the main thread and creating a PCM data with them.



Because AudioFileReader is not a Unity API, you should be able to use it in from Thread. Once you're doing reading the audio's float data from another Thread, you can then do a callback to the main Thread to create AudioClip with the AudioClip.Create function since you can't use this API from the main Thread.



Grab UnityThread that enables easy callback on the main thread from this post then see below for what your new LoadSong function should look like. I used ThreadPool but you can use any other Thread API in C# if you wish.



void Awake()
{
//Enable Callback on the main Thread
UnityThread.initUnityThread();
}

public void LoadSong(string musicPath)
{
ThreadPool.QueueUserWorkItem(delegate
{
//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if (songTitle != currentlyPlaying && songTitle != lastPlayedTitle)
{
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Now, create the clip on the main Thread and also play it
UnityThread.executeInUpdate(() =>
{
//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if (craftClip.isReadyToPlay)
{
playMusic(craftClip, songTitle);

/*Disposing on main thread may also introduce freezing so do that in a Thread too*/
ThreadPool.QueueUserWorkItem(delegate { aud.Dispose(); });
}
});
}
else
{
UnityThread.executeInUpdate(() =>
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
});
}
});
}





share|improve this answer



















  • 1





    Thank you so much! It is now only a tiny blip which is acceptable.

    – JamieD
    Nov 25 '18 at 6:32
















0














Audio is usually loaded with the WWW.GetAudioClip function but since you ran into exceptions with it, you decided to use NAudio. The freezing that happens when AudioFileReader(musicPath) and aud.Read(AudioData, 0, (int)aud.Length) executes makes sense since this constructor and function are trying to load an audio file on the main thread and creating a PCM data with them.



Because AudioFileReader is not a Unity API, you should be able to use it in from Thread. Once you're doing reading the audio's float data from another Thread, you can then do a callback to the main Thread to create AudioClip with the AudioClip.Create function since you can't use this API from the main Thread.



Grab UnityThread that enables easy callback on the main thread from this post then see below for what your new LoadSong function should look like. I used ThreadPool but you can use any other Thread API in C# if you wish.



void Awake()
{
//Enable Callback on the main Thread
UnityThread.initUnityThread();
}

public void LoadSong(string musicPath)
{
ThreadPool.QueueUserWorkItem(delegate
{
//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if (songTitle != currentlyPlaying && songTitle != lastPlayedTitle)
{
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Now, create the clip on the main Thread and also play it
UnityThread.executeInUpdate(() =>
{
//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if (craftClip.isReadyToPlay)
{
playMusic(craftClip, songTitle);

/*Disposing on main thread may also introduce freezing so do that in a Thread too*/
ThreadPool.QueueUserWorkItem(delegate { aud.Dispose(); });
}
});
}
else
{
UnityThread.executeInUpdate(() =>
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
});
}
});
}





share|improve this answer



















  • 1





    Thank you so much! It is now only a tiny blip which is acceptable.

    – JamieD
    Nov 25 '18 at 6:32














0












0








0







Audio is usually loaded with the WWW.GetAudioClip function but since you ran into exceptions with it, you decided to use NAudio. The freezing that happens when AudioFileReader(musicPath) and aud.Read(AudioData, 0, (int)aud.Length) executes makes sense since this constructor and function are trying to load an audio file on the main thread and creating a PCM data with them.



Because AudioFileReader is not a Unity API, you should be able to use it in from Thread. Once you're doing reading the audio's float data from another Thread, you can then do a callback to the main Thread to create AudioClip with the AudioClip.Create function since you can't use this API from the main Thread.



Grab UnityThread that enables easy callback on the main thread from this post then see below for what your new LoadSong function should look like. I used ThreadPool but you can use any other Thread API in C# if you wish.



void Awake()
{
//Enable Callback on the main Thread
UnityThread.initUnityThread();
}

public void LoadSong(string musicPath)
{
ThreadPool.QueueUserWorkItem(delegate
{
//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if (songTitle != currentlyPlaying && songTitle != lastPlayedTitle)
{
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Now, create the clip on the main Thread and also play it
UnityThread.executeInUpdate(() =>
{
//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if (craftClip.isReadyToPlay)
{
playMusic(craftClip, songTitle);

/*Disposing on main thread may also introduce freezing so do that in a Thread too*/
ThreadPool.QueueUserWorkItem(delegate { aud.Dispose(); });
}
});
}
else
{
UnityThread.executeInUpdate(() =>
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
});
}
});
}





share|improve this answer













Audio is usually loaded with the WWW.GetAudioClip function but since you ran into exceptions with it, you decided to use NAudio. The freezing that happens when AudioFileReader(musicPath) and aud.Read(AudioData, 0, (int)aud.Length) executes makes sense since this constructor and function are trying to load an audio file on the main thread and creating a PCM data with them.



Because AudioFileReader is not a Unity API, you should be able to use it in from Thread. Once you're doing reading the audio's float data from another Thread, you can then do a callback to the main Thread to create AudioClip with the AudioClip.Create function since you can't use this API from the main Thread.



Grab UnityThread that enables easy callback on the main thread from this post then see below for what your new LoadSong function should look like. I used ThreadPool but you can use any other Thread API in C# if you wish.



void Awake()
{
//Enable Callback on the main Thread
UnityThread.initUnityThread();
}

public void LoadSong(string musicPath)
{
ThreadPool.QueueUserWorkItem(delegate
{
//Set title of song
songTitle = Path.GetFileNameWithoutExtension(musicPath);
if (songTitle != currentlyPlaying && songTitle != lastPlayedTitle)
{
//Parse the file with NAudio
aud = new AudioFileReader(musicPath);

//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, (int)aud.Length);

//Now, create the clip on the main Thread and also play it
UnityThread.executeInUpdate(() =>
{
//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(songTitle, (int)aud.Length, aud.WaveFormat.Channels, aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData, 0);

if (craftClip.isReadyToPlay)
{
playMusic(craftClip, songTitle);

/*Disposing on main thread may also introduce freezing so do that in a Thread too*/
ThreadPool.QueueUserWorkItem(delegate { aud.Dispose(); });
}
});
}
else
{
UnityThread.executeInUpdate(() =>
{
playMusic(lastPlayedAudioFile, lastPlayedTitle);
});
}
});
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 24 '18 at 16:29









ProgrammerProgrammer

78.8k1091162




78.8k1091162








  • 1





    Thank you so much! It is now only a tiny blip which is acceptable.

    – JamieD
    Nov 25 '18 at 6:32














  • 1





    Thank you so much! It is now only a tiny blip which is acceptable.

    – JamieD
    Nov 25 '18 at 6:32








1




1





Thank you so much! It is now only a tiny blip which is acceptable.

– JamieD
Nov 25 '18 at 6:32





Thank you so much! It is now only a tiny blip which is acceptable.

– JamieD
Nov 25 '18 at 6:32




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446540%2fusing-naudio-to-create-audioclip-in-unity-freezes-1-2-seconds-while-reading-dat%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Paul Cézanne

UIScrollView CustomStickyHeader Resize height generates problems when scroll is too fast

Angular material date-picker (MatDatepicker) auto completes the date on focus out