├── README ├── UnityFreesound.unitypackage └── src ├── FreesoundAudioPlayer.cs ├── FreesoundBrowser.cs ├── FreesoundConfig.cs ├── FreesoundHandler.cs ├── JsonFx.Json.dll ├── License_JsonFX.txt ├── freesound_logo_small.png └── waveform_placeholder.png /README: -------------------------------------------------------------------------------- 1 | UnityFreesound - Editor tool for Unity3d 2 | 3 | Browse, preview, download and credit sounds 4 | from Freesound.org within the Unity editor. 5 | 6 | Author: Jorge Garcia [info@jorgegarciamartin.com] 7 | 8 | ------------------------------------------------------------- 9 | 10 | Import the "UnityFreesound.unitypackage" in your Unity project. Otherwise, you can directly import the contents of the /src folder into your /Editor folder of your Unity project. You will find afterwards two new entries in the Window menu: 11 | 12 | - Freesound Browser. Allows searching and browsing sounds for keywords/tags, listen to a preview of the sounds (to STOP after PLAY, press space bar), go to Freesound.org for a more detailed description if you click on the waveforms, and import the sounds to a user defined folder (/Freesound folder is used as default). 13 | 14 | - Freesound Config and Credits. Here you can define a folder where the sounds will be stored. Additionally, it allows exporting the sounds metadata to CSV format, so you can easily credit sounds from Freesound in your application :) 15 | 16 | TODO (22.02.2012): 17 | - Upload user manual with screen captures. 18 | - Add examples of usage. 19 | - Add Freesound advanced search settings. 20 | - Include a download manager. 21 | - Improve preview player. 22 | 23 | Thanks to Roel Sanchez [roel.san@gmail.com] [http://www.roelsanchez.net/] for testing this out, providing feedback and additional feature requests. 24 | 25 | This Editor tool uses a JSonFX [https://github.com/jsonfx/jsonfx] distribution for Unity3d by The Dark Table [http://the.darktable.com/] 26 | 27 | Please visit the Freesound API docs for additional information [http://www.freesound.org/docs/api/] 28 | -------------------------------------------------------------------------------- /UnityFreesound.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jorgegarcia/UnityFreesound/4cf26e3f17d816ad98804ec7c727ee6f126b89ab/UnityFreesound.unitypackage -------------------------------------------------------------------------------- /src/FreesoundAudioPlayer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | [RequireComponent(typeof(AudioSource))] 5 | public class FreesoundAudioPlayer : MonoBehaviour 6 | { 7 | private static FreesoundAudioPlayer instance_; 8 | 9 | static FreesoundAudioPlayer(){} 10 | 11 | private FreesoundAudioPlayer(){} 12 | 13 | public static FreesoundAudioPlayer Instance 14 | { 15 | get 16 | { 17 | instance_ = (FreesoundAudioPlayer)GameObject.FindObjectOfType(typeof(FreesoundAudioPlayer)); 18 | 19 | if(instance_ == null) 20 | { 21 | instance_ = new GameObject("FreesoundAudioPlayer").AddComponent(); 22 | } 23 | 24 | return instance_; 25 | } 26 | } 27 | 28 | public void StartStream (string url) 29 | { 30 | if(audio.isPlaying) audio.Stop(); 31 | 32 | WWW audioStreamer = new WWW (url); 33 | audio.clip = audioStreamer.audioClip; 34 | 35 | EditorUtility.DisplayProgressBar("Buffering preview from Freesound.org ...", "", 0.5f); 36 | 37 | //Block and wait for audio buffering 38 | //TODO: would prefer handling it at Update() 39 | //so to allow different streams playing concurrently 40 | while(!audio.clip.isReadyToPlay) 41 | { 42 | if(audioStreamer.error != null) 43 | { 44 | UnityEditor.EditorUtility.DisplayDialog("UnityFreesound Request ERROR!", 45 | "Can't process the request." + 46 | "\n\nError: " + audioStreamer.error, "OK"); 47 | EditorUtility.ClearProgressBar(); 48 | return; 49 | } 50 | 51 | } 52 | 53 | EditorUtility.ClearProgressBar(); 54 | 55 | audio.Play(); 56 | } 57 | 58 | public void StopStream() 59 | { 60 | audio.Stop(); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/FreesoundBrowser.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Reflection; 6 | using System.Net; 7 | using System.ComponentModel; 8 | 9 | public class FreesoundBrowser : EditorWindow 10 | { 11 | private Vector2 scroll_; 12 | private string[] searchOptions_ = {"Duration (long first)", //0 13 | "Duration (short first)", //1 14 | "Date added (newest first)", //2 15 | "Date added (oldest first)", //3 16 | "Downloads (most first)", //4 17 | "Downloads (least first)", //5 18 | "Rating (highest first)", //6 19 | "Rating (lowest first)", //7 20 | }; 21 | private string[] allowedFormats_ = {"aif", "mp3", "ogg", "wav"}; 22 | private string searchQuery_ = ""; 23 | private int sortIndex_ = 4;//Default is "Downloads (most first)" 24 | private int downloadProgress_ = 0; 25 | private int previousDownloadProgress_ = 0; 26 | private float timer_ = 0.0f; 27 | private const float freesoundTimeout_ = 10.0f; 28 | private static GUIStyle waveformStyle_ = new GUIStyle(); 29 | 30 | //Browser states 31 | private bool searchPressed_ = false; 32 | private bool responseProcessed_ = false; 33 | private bool resetScroll_ = false; 34 | private bool importPressed_ = false; 35 | private bool downloadCompleted_ = false; 36 | private bool downloadTimeout_ = false; 37 | 38 | //Request containers and cache 39 | private FreesoundLogData lastData_ = new FreesoundLogData(); 40 | private WWW www_ = null; 41 | private WebClient importClient_ = null; 42 | private Dictionary response_ = null; 43 | private List soundWaveforms_ = new List(); 44 | private List waveformWWWRequests_ = new List(); 45 | private List waveformsCached_ = new List(); 46 | 47 | [MenuItem("Window/Freesound Browser %#x")] 48 | static void Init() 49 | { 50 | FreesoundBrowser window = (FreesoundBrowser)EditorWindow.GetWindow (typeof(FreesoundBrowser), 51 | true, "Freesound Browser"); 52 | waveformStyle_.alignment = TextAnchor.MiddleCenter; 53 | 54 | window.Show(); 55 | } 56 | 57 | void OnGUI() 58 | { 59 | EditorGUILayout.BeginHorizontal(); 60 | 61 | searchQuery_ = EditorGUILayout.TextField(searchQuery_); 62 | sortIndex_ = EditorGUILayout.Popup(sortIndex_, searchOptions_); 63 | 64 | if(GUILayout.Button("SEARCH") || 65 | (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Return)) 66 | { 67 | searchPressed_ = true; 68 | responseProcessed_ = false; 69 | } 70 | 71 | if(Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Space) 72 | FreesoundAudioPlayer.Instance.StopStream(); 73 | 74 | EditorGUILayout.EndHorizontal(); 75 | 76 | scroll_ = GUILayout.BeginScrollView(scroll_); 77 | 78 | DisplayResults(); 79 | 80 | EditorGUILayout.EndScrollView(); 81 | } 82 | 83 | void Update() 84 | { 85 | #region SEARCH PRESSED 86 | if(searchPressed_) 87 | { 88 | searchPressed_ = false; 89 | ProcessFirstQuery(searchQuery_, sortIndex_); 90 | } 91 | 92 | if(www_ != null) 93 | { 94 | if(www_.isDone && www_.error == null) 95 | { 96 | try 97 | { 98 | //Thanks to https://bitbucket.org/darktable/jsonfx-for-unity3d/downloads 99 | Assembly jsonAssembly = Assembly.LoadFrom(Application.dataPath + "/Editor/UnityFreesound/JsonFx.Json.dll"); 100 | Type jsonAssemblyType = jsonAssembly.GetType("JsonFx.Json.JsonReader"); 101 | //Calling the static method "Deserialize" returning a Dictionary (default JsonReader call) 102 | response_ = (Dictionary)jsonAssemblyType.InvokeMember("Deserialize", 103 | BindingFlags.InvokeMethod, null, 104 | Activator.CreateInstance(typeof(object)), 105 | new object[]{ www_.text }); 106 | } 107 | catch(Exception e) 108 | { 109 | UnityEditor.EditorUtility.DisplayDialog("UnityFreesound Request ERROR!", 110 | "Can't process the request. Please try again." + 111 | "\n\nException thrown: " + e.Message, "OK"); 112 | } 113 | 114 | //Filter here only the file types allowed in allowedFormats_ 115 | FilterSoundsByFormat(ref response_); 116 | object[] sounds = (object[])response_["sounds"]; 117 | SpawnWaveformsCache(ref sounds); 118 | EditorUtility.ClearProgressBar(); 119 | responseProcessed_ = true; 120 | resetScroll_ = true; 121 | 122 | www_ = null; 123 | } 124 | else if(www_.isDone && www_.error != null) 125 | { 126 | UnityEditor.EditorUtility.DisplayDialog("UnityFreesound Request ERROR!", 127 | "Can't process the request." + 128 | "\n\nError: " + www_.error, "OK"); 129 | EditorUtility.ClearProgressBar(); 130 | responseProcessed_ = true; 131 | resetScroll_ = true; 132 | 133 | www_ = null; 134 | } 135 | else 136 | { 137 | EditorUtility.DisplayProgressBar("Loading...", "Searching Freesound for ''" + searchQuery_ + "''", 0.5f); 138 | } 139 | } 140 | #endregion 141 | 142 | #region IMPORT PRESSED 143 | if(importPressed_) 144 | { 145 | EditorUtility.DisplayProgressBar("Downloading sound...", "Completed " + downloadProgress_ + " %", 146 | (float)downloadProgress_/100.0f); 147 | 148 | if((downloadProgress_ == previousDownloadProgress_) && !downloadTimeout_) 149 | { 150 | timer_ += Time.fixedDeltaTime; 151 | previousDownloadProgress_ = downloadProgress_; 152 | //Debug.Log("Import timeout: " + timer_.ToString()); 153 | 154 | if(timer_ > freesoundTimeout_) 155 | { 156 | importClient_.CancelAsync(); 157 | DisposeImportState(); 158 | System.IO.File.Delete(lastData_.localPath);//Clean-up WebClient file 159 | 160 | EditorUtility.ClearProgressBar(); 161 | UnityEditor.EditorUtility.DisplayDialog("UnityFreesound Request ERROR!", 162 | "Request timeout. Sound not imported.", "OK"); 163 | } 164 | } 165 | else 166 | { 167 | previousDownloadProgress_ = downloadProgress_; 168 | timer_ = 0.0f; 169 | } 170 | 171 | if(downloadCompleted_ && !downloadTimeout_) 172 | { 173 | EditorUtility.ClearProgressBar(); 174 | DisposeImportState(); 175 | 176 | FreesoundHandler.Instance.AddSoundToCredits(lastData_.filename, lastData_.id, lastData_.localPath, 177 | lastData_.url, lastData_.user); 178 | EditorApplication.SaveAssets(); 179 | AssetDatabase.Refresh(); 180 | } 181 | } 182 | #endregion 183 | 184 | #region RESPONSE PROCESSED 185 | if(responseProcessed_) 186 | { 187 | object[] sounds = (object[])response_["sounds"]; 188 | 189 | for(int i = 0; i < sounds.Length; i++) 190 | { 191 | if(waveformWWWRequests_[i].isDone && !waveformsCached_[i] && waveformWWWRequests_[i].error == null) 192 | { 193 | soundWaveforms_[i] = waveformWWWRequests_[i].texture; 194 | waveformsCached_[i] = true; 195 | } 196 | } 197 | 198 | Repaint(); 199 | } 200 | #endregion 201 | } 202 | 203 | private void FilterSoundsByFormat(ref Dictionary response) 204 | { 205 | object[] sounds = (object[])response["sounds"]; 206 | 207 | List filtered = new List(); 208 | 209 | foreach(object sound in sounds) 210 | { 211 | var soundDictionary = (Dictionary)sound; 212 | 213 | foreach(string typeAllowed in allowedFormats_) 214 | { 215 | if(String.Equals(soundDictionary["type"], typeAllowed)) 216 | { 217 | filtered.Add(sound); break; 218 | } 219 | } 220 | } 221 | 222 | response["sounds"] = filtered.ToArray(); 223 | } 224 | 225 | private void ProcessFirstQuery(string query, int sortIndex) 226 | { 227 | UriBuilder queryBuilder = new UriBuilder("http", "www.freesound.org"); 228 | queryBuilder.Path = "/api/sounds/search"; 229 | string sortMode = ""; 230 | 231 | switch(sortIndex) 232 | { 233 | case 0: 234 | sortMode = "duration_desc"; 235 | break; 236 | case 1: 237 | sortMode = "duration_asc"; 238 | break; 239 | case 2: 240 | sortMode = "created_desc"; 241 | break; 242 | case 3: 243 | sortMode = "created_asc"; 244 | break; 245 | case 4: 246 | sortMode = "downloads_desc"; 247 | break; 248 | case 5: 249 | sortMode = "downloads_asc"; 250 | break; 251 | case 6: 252 | sortMode = "rating_desc"; 253 | break; 254 | case 7: 255 | sortMode = "rating_asc"; 256 | break; 257 | } 258 | 259 | query = query.Replace(" ", "+");//replace spaces with AND operator (default) 260 | queryBuilder.Query += "p=1" + "&q=" + query + "&s=" + sortMode + "&api_key=" + FreesoundHandler.Instance.ApiKey; 261 | www_ = new WWW(queryBuilder.ToString()); 262 | } 263 | 264 | private void DisplayResults() 265 | { 266 | if(responseProcessed_) 267 | { 268 | if(resetScroll_) 269 | { 270 | scroll_.x = scroll_.y = 0.0f; 271 | resetScroll_ = false; 272 | } 273 | 274 | object[] sounds = (object[])response_["sounds"]; 275 | 276 | GUILayout.Label("Number of results: " + response_["num_results"].ToString()); 277 | 278 | int soundCounter = 0; 279 | foreach(object sound in sounds) 280 | { 281 | var soundDictionary = (Dictionary)sound; 282 | 283 | GUILayout.BeginHorizontal(); 284 | 285 | GUILayout.Space(10); 286 | 287 | if(GUILayout.Button(soundWaveforms_[soundCounter], waveformStyle_)) 288 | Application.OpenURL(soundDictionary["url"].ToString()); 289 | 290 | GUILayout.BeginVertical(); 291 | 292 | if(GUILayout.Button("\nPLAY\n")) 293 | { 294 | FreesoundAudioPlayer.Instance.StartStream(soundDictionary["preview-lq-ogg"].ToString()); 295 | } 296 | 297 | GUILayout.Space(6); 298 | 299 | if(GUILayout.Button("IMPORT")) 300 | { 301 | importPressed_ = true; 302 | 303 | //TODO: refactor. Change WebClient to HttpWebRequest to handle timeouts better 304 | importClient_ = new WebClient(); 305 | importClient_.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged); 306 | importClient_.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); 307 | Uri request = new Uri(soundDictionary["serve"] + "?api_key=" + FreesoundHandler.Instance.ApiKey); 308 | 309 | //If the user hasn't defined a default folder at Freesound configuration 310 | //then create it at /Assets/Freesound/ 311 | if(String.IsNullOrEmpty(FreesoundHandler.Instance.FreesoundDownloadsPath)) 312 | { 313 | System.IO.Directory.CreateDirectory(Application.dataPath + "/Freesound"); 314 | FreesoundHandler.Instance.FreesoundDownloadsPath = Application.dataPath + "/Freesound"; 315 | FreesoundHandler.Instance.FreesoundDownloads = "/Freesound"; 316 | } 317 | 318 | string lastDownloadedFilePath = FreesoundHandler.Instance.FreesoundDownloadsPath + 319 | "/" + soundDictionary["original_filename"].ToString(); 320 | 321 | try 322 | { 323 | importClient_.DownloadFileAsync(request, lastDownloadedFilePath); 324 | 325 | //Cache log data to be used in async loading completion 326 | Dictionary userDataName = (Dictionary)soundDictionary["user"]; 327 | 328 | lastData_.filename = soundDictionary["original_filename"].ToString(); 329 | lastData_.id = soundDictionary["id"].ToString(); 330 | lastData_.url = soundDictionary["url"].ToString(); 331 | lastData_.user = userDataName["username"].ToString(); 332 | lastData_.localPath = lastDownloadedFilePath; 333 | } 334 | catch(WebException e) 335 | { 336 | UnityEditor.EditorUtility.DisplayDialog("UnityFreesound Request ERROR!", 337 | "Can't process the request." + "\n\nException thrown: " + e.Message, 338 | "OK"); 339 | } 340 | } 341 | 342 | GUILayout.EndVertical(); 343 | 344 | GUILayout.BeginVertical(); 345 | 346 | EditorGUILayout.LabelField("File name", soundDictionary["original_filename"].ToString()); 347 | int point = soundDictionary["duration"].ToString().IndexOf("."); 348 | 349 | if(point != -1) 350 | { 351 | if(soundDictionary["duration"].ToString().Length > 5) 352 | EditorGUILayout.LabelField("Duration (secs)", soundDictionary["duration"].ToString().Substring(0, 5)); 353 | else 354 | EditorGUILayout.LabelField("Duration (secs)", soundDictionary["duration"].ToString()); 355 | } 356 | else 357 | { 358 | EditorGUILayout.LabelField("Duration (secs)", soundDictionary["duration"].ToString()); 359 | } 360 | 361 | Dictionary userData = (Dictionary)soundDictionary["user"]; 362 | EditorGUILayout.LabelField("User", userData["username"].ToString()); 363 | 364 | object[] tags = (object[])soundDictionary["tags"]; 365 | 366 | if(tags.Length > 0) 367 | EditorGUILayout.Popup("Tags", 0, (string[])tags); 368 | else 369 | EditorGUILayout.LabelField("Tags", "Sound untagged"); 370 | 371 | GUILayout.EndVertical(); 372 | 373 | GUILayout.EndHorizontal(); 374 | 375 | GUILayout.Space(10); 376 | soundCounter++; 377 | } 378 | 379 | GUILayout.BeginHorizontal(); 380 | 381 | GUILayout.Space(10); 382 | 383 | if(response_.ContainsKey("previous")) 384 | { 385 | if(GUILayout.Button("Previous results")) 386 | { 387 | string searchQuery = response_["previous"].ToString() + "&api_key=" + FreesoundHandler.Instance.ApiKey; 388 | responseProcessed_ = false; 389 | www_ = new WWW(searchQuery); 390 | } 391 | } 392 | if(response_.ContainsKey("next")) 393 | { 394 | if(GUILayout.Button("Next results")) 395 | { 396 | string searchQuery = response_["next"].ToString() + "&api_key=" + FreesoundHandler.Instance.ApiKey; 397 | responseProcessed_ = false; 398 | www_ = new WWW(searchQuery); 399 | } 400 | } 401 | 402 | GUILayout.Space(10); 403 | 404 | GUILayout.EndHorizontal(); 405 | 406 | GUILayout.Space(10); 407 | } 408 | else 409 | { 410 | GUILayout.Label("Search for keywords/tags in the field above to browse sounds..."); 411 | } 412 | } 413 | 414 | private void SpawnWaveformsCache(ref object[] sounds) 415 | { 416 | Texture2D placeholder = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/Editor/UnityFreesound/waveform_placeholder.png", 417 | typeof(Texture2D)); 418 | soundWaveforms_.Clear(); 419 | waveformWWWRequests_.Clear(); 420 | waveformsCached_.Clear(); 421 | 422 | foreach(object sound in sounds) 423 | { 424 | var soundDictionary = (Dictionary)sound; 425 | soundWaveforms_.Add(placeholder); 426 | WWW www = new WWW(soundDictionary["waveform_m"].ToString()); 427 | waveformWWWRequests_.Add(www); 428 | waveformsCached_.Add(false); 429 | } 430 | } 431 | 432 | private void DisposeImportState() 433 | { 434 | importClient_.Dispose(); 435 | importPressed_ = false; 436 | downloadCompleted_ = false; 437 | downloadTimeout_ = false; 438 | downloadProgress_ = 0; 439 | timer_ = 0.0f; 440 | } 441 | 442 | #region WebClient Events 443 | private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e) 444 | { 445 | downloadProgress_ = e.ProgressPercentage; 446 | } 447 | 448 | private void Completed(object sender, AsyncCompletedEventArgs e) 449 | { 450 | downloadCompleted_ = true; 451 | 452 | if(e.Cancelled) 453 | downloadTimeout_ = true; 454 | } 455 | #endregion 456 | } 457 | 458 | -------------------------------------------------------------------------------- /src/FreesoundConfig.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | public class FreesoundConfig : EditorWindow 5 | { 6 | private static Texture2D freesoundLogo_; 7 | private static GUIStyle style = new GUIStyle(); 8 | private Vector2 scroll_; 9 | 10 | [MenuItem("Window/Freesound Config and Credits")] 11 | static void Init() 12 | { 13 | FreesoundConfig window = (FreesoundConfig)EditorWindow.GetWindow (typeof(FreesoundConfig), 14 | true, "Freesound Config and Credits"); 15 | 16 | string logoPath = "Assets/Editor/UnityFreesound/freesound_logo_small.png"; 17 | freesoundLogo_ = (Texture2D)AssetDatabase.LoadAssetAtPath(logoPath, typeof(Texture2D)); 18 | 19 | style.alignment = TextAnchor.MiddleCenter; 20 | 21 | window.Show(); 22 | } 23 | 24 | void OnGUI() 25 | { 26 | // Logo and link to Freesound.org 27 | if(GUILayout.Button(freesoundLogo_, style)) Application.OpenURL("http://www.freesound.org"); 28 | EditorGUILayout.Separator(); 29 | 30 | // API Key 31 | EditorGUILayout.LabelField("API KEY", FreesoundHandler.Instance.ApiKey); 32 | EditorGUILayout.Separator(); 33 | 34 | // Asset folder (where the downloaded Freesound sounds will be stored) 35 | EditorGUILayout.BeginHorizontal(); 36 | EditorGUILayout.LabelField("AUDIO FOLDER", FreesoundHandler.Instance.FreesoundDownloads); 37 | if(GUILayout.Button("Change...")) 38 | { 39 | FreesoundHandler.Instance.FreesoundDownloadsPath = EditorUtility.SaveFolderPanel("Select download folder...", Application.dataPath, ""); 40 | 41 | if(!System.String.IsNullOrEmpty(FreesoundHandler.Instance.FreesoundDownloadsPath)) 42 | { 43 | int lastSlash = FreesoundHandler.Instance.FreesoundDownloadsPath.LastIndexOf("/"); 44 | FreesoundHandler.Instance.FreesoundDownloads = FreesoundHandler.Instance.FreesoundDownloadsPath.Substring(lastSlash); 45 | } 46 | } 47 | EditorGUILayout.EndHorizontal(); 48 | EditorGUILayout.Separator(); 49 | 50 | // Allow exporting Freesound data as CSV... 51 | if(FreesoundHandler.Instance.FileNames.Count > 0) 52 | { 53 | // Freesound credits 54 | GUILayout.Label("List of sounds imported in this project..."); 55 | scroll_ = GUILayout.BeginScrollView(scroll_); 56 | GUILayout.Label(System.String.Join("\n", FreesoundHandler.Instance.GetFormattedLogData())); 57 | EditorGUILayout.EndScrollView(); 58 | EditorGUILayout.Separator(); 59 | 60 | if(GUILayout.Button("Export sounds full data to .csv")) 61 | { 62 | string destinationPath = EditorUtility.SaveFilePanel("Select folder to save credits...", "", "Freesound_credits", "csv"); 63 | System.IO.File.WriteAllLines(destinationPath, FreesoundHandler.Instance.GetFormattedCSVData()); 64 | } 65 | 66 | EditorGUILayout.Separator(); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/FreesoundHandler.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | struct FreesoundLogData 5 | { 6 | public string filename; 7 | public string user; 8 | public string id; 9 | public string localPath; 10 | public string url; 11 | } 12 | 13 | public class FreesoundHandler : MonoBehaviour 14 | { 15 | private static FreesoundHandler instance_; 16 | 17 | static FreesoundHandler(){} 18 | 19 | private FreesoundHandler(){} 20 | 21 | public static FreesoundHandler Instance 22 | { 23 | get 24 | { 25 | instance_ = (FreesoundHandler)GameObject.FindObjectOfType(typeof(FreesoundHandler)); 26 | 27 | if(instance_ == null) 28 | { 29 | instance_ = new GameObject("FreesoundHandler").AddComponent(); 30 | instance_.fileNames = new List(); 31 | instance_.freesoundIds = new List(); 32 | instance_.users = new List(); 33 | instance_.freesoundURLs = new List(); 34 | instance_.localPaths = new List(); 35 | } 36 | 37 | return instance_; 38 | } 39 | } 40 | 41 | #region Member Variables 42 | [SerializeField] 43 | private string freesoundDownloadsPath_ = ""; 44 | 45 | [SerializeField] 46 | private string freesoundDownloads_ = ""; 47 | 48 | //Using Lists instead of a struct in order to allow 49 | //serializing the data within the Unity project... 50 | [SerializeField] 51 | private List fileNames; 52 | 53 | [SerializeField] 54 | private List freesoundIds; 55 | 56 | [SerializeField] 57 | private List users; 58 | 59 | [SerializeField] 60 | private List localPaths; 61 | 62 | [SerializeField] 63 | private List freesoundURLs; 64 | #endregion 65 | 66 | private const string apiKey_ = "8d83cf5d9b7842399ec1bae7a23b6bb5"; 67 | 68 | #region Properties 69 | public List FileNames 70 | { 71 | get 72 | { 73 | return fileNames; 74 | } 75 | } 76 | 77 | public List FreesoundIds 78 | { 79 | get 80 | { 81 | return freesoundIds; 82 | } 83 | } 84 | 85 | public List Users 86 | { 87 | get 88 | { 89 | return users; 90 | } 91 | } 92 | 93 | public List LocalPaths 94 | { 95 | get 96 | { 97 | return localPaths; 98 | } 99 | } 100 | 101 | public List FreesoundURLS 102 | { 103 | get 104 | { 105 | return freesoundURLs; 106 | } 107 | } 108 | 109 | 110 | public string ApiKey 111 | { 112 | get 113 | { 114 | return apiKey_; 115 | } 116 | } 117 | 118 | public string FreesoundDownloadsPath 119 | { 120 | get 121 | { 122 | return freesoundDownloadsPath_; 123 | } 124 | 125 | set 126 | { 127 | freesoundDownloadsPath_ = value; 128 | } 129 | } 130 | 131 | public string FreesoundDownloads 132 | { 133 | get 134 | { 135 | return freesoundDownloads_; 136 | } 137 | 138 | set 139 | { 140 | freesoundDownloads_ = value; 141 | } 142 | } 143 | #endregion 144 | 145 | #region Methods 146 | private void UpdateFileLog() 147 | { 148 | if(fileNames.Count > 0) 149 | { 150 | List fileIndexesToRemove = new List(); 151 | 152 | for(int i = 0; i < fileNames.Count; i++) 153 | { 154 | if(!System.IO.File.Exists(localPaths[i])) 155 | fileIndexesToRemove.Add(i); 156 | } 157 | 158 | for(int index = fileIndexesToRemove.Count - 1; index >= 0; index--) 159 | { 160 | fileNames.RemoveAt(fileIndexesToRemove[index]); 161 | freesoundURLs.RemoveAt(fileIndexesToRemove[index]); 162 | localPaths.RemoveAt(fileIndexesToRemove[index]); 163 | users.RemoveAt(fileIndexesToRemove[index]); 164 | freesoundIds.RemoveAt(fileIndexesToRemove[index]); 165 | } 166 | 167 | } 168 | } 169 | 170 | 171 | public void AddSoundToCredits(string fileName, string id, string localPath, 172 | string url, string user) 173 | { 174 | bool fileRegistered = false; 175 | 176 | if(fileNames.Count > 0) 177 | { 178 | foreach(string fileId in freesoundIds) 179 | { 180 | if(fileId == id) 181 | { 182 | fileRegistered = true; 183 | break; 184 | } 185 | } 186 | } 187 | 188 | //If the file hasn't been registered yet, then add it 189 | if(!fileRegistered) 190 | { 191 | freesoundURLs.Add(url); 192 | LocalPaths.Add(localPath); 193 | users.Add(user); 194 | fileNames.Add(fileName); 195 | freesoundIds.Add(id); 196 | } 197 | } 198 | 199 | public string[] GetFormattedLogData() 200 | { 201 | List outBuffer = new List(); 202 | 203 | UpdateFileLog(); 204 | 205 | for(int i = 0; i < fileNames.Count; i++) 206 | { 207 | outBuffer.Add(fileNames[i] + " by " + users[i]); 208 | } 209 | 210 | return outBuffer.ToArray(); 211 | } 212 | 213 | public string[] GetFormattedCSVData() 214 | { 215 | List outBuffer = new List(); 216 | 217 | //Add column headers first.. 218 | outBuffer.Add("FileName;User;FreesoundID;LocalPath;FreesoundURL"); 219 | 220 | for(int i = 0; i < fileNames.Count; i++) 221 | { 222 | string[] temp = { fileNames[i], users[i], freesoundIds[i], localPaths[i], freesoundURLs[i] }; 223 | outBuffer.Add(string.Join(";", temp)); 224 | } 225 | 226 | return outBuffer.ToArray(); 227 | } 228 | #endregion 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /src/JsonFx.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jorgegarcia/UnityFreesound/4cf26e3f17d816ad98804ec7c727ee6f126b89ab/src/JsonFx.Json.dll -------------------------------------------------------------------------------- /src/License_JsonFX.txt: -------------------------------------------------------------------------------- 1 | Distributed under the terms of an MIT-style license: 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2006-2009 Stephen M. McKamey 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/freesound_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jorgegarcia/UnityFreesound/4cf26e3f17d816ad98804ec7c727ee6f126b89ab/src/freesound_logo_small.png -------------------------------------------------------------------------------- /src/waveform_placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jorgegarcia/UnityFreesound/4cf26e3f17d816ad98804ec7c727ee6f126b89ab/src/waveform_placeholder.png --------------------------------------------------------------------------------