//Empieza a reproducir la música private void PlayMusic() { OSCHandler.Instance.SendMessageToClient(ClientId, "/Play", package.ToString()); //TODO: hacer que empiecen las capas que sea sonando //NOTA: los FX no pueden empezar activos string[] aspects = { "Rhythm", "Harmony", "Melody" }; for (int i = 0; i < MM.Constants.NUM_ASPECTS - 1; i++) { for (int j = 0; j < MM.Constants.MAX_LAYERS; j++) { if (activeLayers[i, j]) { OSCHandler.Instance.SendMessageToClient(ClientId, "/PlayLayer", aspects[i] + " " + j); } } } }
// NOTA: el usuario debe inicializar sus variables en el Awake para que en la primera vuelta todo esté bajo control // (mejor rendimiento porque ahorra una vuelta de mensajes) // Aquí se hace que solo queden tuplas válidas para no tener que comprobarlo en cada tick private void Start() { if (EditorApplication.isPlaying) { //Paquete actual string packageData = File.ReadAllText(MM.Utils.GetPackageFile()); package = (MM.Package)Enum.Parse(typeof(MM.Package), packageData); //Capas string layersFile = MM.Utils.GetLayersFile(); Debug.Assert(File.Exists(layersFile)); string layersData = File.ReadAllText(layersFile); //TODO: se prodía hacer una estructura única para representar el array bidimensional de 4x4. Más fácil de usar //Inicializamos los valores de las capas int c = 0; activeLayers = new bool[MM.Constants.NUM_ASPECTS, MM.Constants.MAX_LAYERS]; for (int i = 0; i < MM.Constants.NUM_ASPECTS; i++) //ESTE CÓDIGO ESTÁ REPE { for (int j = 0; j < MM.Constants.MAX_LAYERS; j++) { activeLayers[i, j] = layersData[c++] == '1' ? true : false; } } //Para asegurarnos de que hay paquete elegido Debug.Assert(package != MM.Package.None); //Iniciamos SuperCollider: //a) Crea el cliente de SuperCollider en la dirección de loopback //b) Crea el servidor para recibir mensajes de SuperCollider OSCHandler.Instance.Init(); //Eliminar tuplas no válidas tuples.RemoveAll(x => !x.IsCorrect()); //Inicializar los valores auxiliares copiando de los originales varValues = new List <object>(); foreach (MM.MusicTuple t in tuples) { varValues.Add(t.input.GetValue()); } //Le mandamos el tipo de paquete al cliente de SuperCollider OSCHandler.Instance.SendMessageToClient(ClientId, "/Init", package.ToString()); //Damos tiempo pa que se inicialice antes de reproducir la música Invoke("PlayMusic", 10.0f); } }
/* * "Tick" de la ventana (para mostrar cosas al usuario) */ void OnGUI() { //Selección de paquete GUILayout.Label("Selección de paquete temático", EditorStyles.boldLabel); package = (MM.Package)EditorGUILayout.EnumPopup("Elige un paquete:", package); //Hay un paquete seleccionado if (package != MM.Package.None) { //Personalizar paquete customPackage = EditorGUILayout.BeginToggleGroup("Personalizar paquete", customPackage); //Capa rítmica var indent = EditorGUI.indentLevel; openFolds[0] = EditorGUILayout.Foldout(openFolds[0], "Ritmo"); if (openFolds[0]) { EditorGUI.indentLevel++; layers[0, 0] = EditorGUILayout.Toggle("Percusión base", layers[0, 0]); layers[0, 1] = EditorGUILayout.Toggle("Percusión secundaria", layers[0, 1]); layers[0, 2] = EditorGUILayout.Toggle("Efectos", layers[0, 2]); } //Capa armónica EditorGUI.indentLevel = indent; openFolds[1] = EditorGUILayout.Foldout(openFolds[1], "Armonía"); if (openFolds[1]) { EditorGUI.indentLevel++; layers[1, 0] = EditorGUILayout.Toggle("Progresión de acordes", layers[1, 0]); layers[1, 1] = EditorGUILayout.Toggle("Acordes octavados", layers[1, 1]); } //Capa melódica EditorGUI.indentLevel = indent; openFolds[2] = EditorGUILayout.Foldout(openFolds[2], "Melodía"); if (openFolds[2]) { EditorGUI.indentLevel++; layers[2, 0] = EditorGUILayout.Toggle("Melodía aleatoria", layers[2, 0]); layers[2, 1] = EditorGUILayout.Toggle("Clichés (1)", layers[2, 1]); layers[2, 2] = EditorGUILayout.Toggle("Clichés (2)", layers[2, 2]); } //Capa de efectos //EditorGUI.indentLevel = indent; //openFolds[3] = EditorGUILayout.Foldout(openFolds[3], "FX"); //if (openFolds[3]) //{ // EditorGUI.indentLevel++; // layers[3, 0] = EditorGUILayout.Toggle("Fx 1", layers[3, 0]); // layers[3, 1] = EditorGUILayout.Toggle("Fx 2", layers[3, 1]); // layers[3, 2] = EditorGUILayout.Toggle("Fx 3", layers[3, 2]); // layers[3, 3] = EditorGUILayout.Toggle("Fx 4", layers[3, 3]); //} //Tempo deseado EditorGUI.indentLevel = indent; tempo = EditorGUILayout.Slider("Tempo (sobre el base)", tempo, 0.5f, 1.5f); //Termina la personalización EditorGUILayout.EndToggleGroup(); } //GUARDA LOS CAMBIOS if (GUILayout.Button("Guardar cambios")) { //Se ha elegido algún paquete if (package != MM.Package.None) { //Guardamos en EditorPrefs y también en archivo para que luego lo lea el MonoBehaviour EditorPrefs.SetString("PackageType", package.ToString()); File.WriteAllText(packageFile, package.ToString()); //Guardamos las capas como un string string layersStr = ""; for (int i = 0; i < MM.Constants.NUM_ASPECTS; i++) { for (int j = 0; j < MM.Constants.MAX_LAYERS; j++) { layersStr += layers[i, j] ? '1' : '0'; } } //Vemos si se ha personalizado el paquete o no userMsg = "Has elegido el paquete " + package.ToString(); if (layersStr != defaultLayers && customPackage) { userMsg += " (Personalizado)"; } else { customPackage = false; } //Escribimos a disco las capas File.WriteAllText(layersFile, layersStr); //Si no existe el GO, lo creamos GameObject musicMaker = GameObject.Find("MusicMaker"); if (!musicMaker) { //Creamos el MusicMaker musicMaker = new GameObject("MusicMaker"); musicMaker.AddComponent <MusicMaker>(); } } //No se ha elegido else { //Borrar el archivo con el nombre y el GameObject userMsg = "Ningún paquete seleccionado"; if (File.Exists(packageFile)) { File.Delete(packageFile); GameObject MMgo = GameObject.Find("MusicMaker"); if (MMgo) { DestroyImmediate(MMgo); } } if (File.Exists(layersFile)) { File.Delete(layersFile); } } } //Mensaje al usuario GUILayout.Label(userMsg, EditorStyles.boldLabel); }