wav converter for mp3
This commit is contained in:
parent
88b21877ca
commit
961a2152b3
|
|
@ -73,6 +73,9 @@ namespace HeavenStudio
|
|||
public event Action<double> onBeatChanged;
|
||||
public event Action<RiqEntity, RiqEntity> onSectionChange;
|
||||
public event Action<double> onBeatPulse;
|
||||
public event Action<double> onPlay;
|
||||
public event Action<double> onPause;
|
||||
public event Action<double> onUnPause;
|
||||
|
||||
public int BeatmapEntities()
|
||||
{
|
||||
|
|
@ -143,9 +146,6 @@ namespace HeavenStudio
|
|||
eventCaller = this.gameObject.AddComponent<EventCaller>();
|
||||
eventCaller.GamesHolder = GamesHolder.transform;
|
||||
eventCaller.Init();
|
||||
Conductor.instance.SetBpm(120f);
|
||||
Conductor.instance.SetVolume(100f);
|
||||
Conductor.instance.firstBeatOffset = Beatmap.data.offset;
|
||||
|
||||
// note: serialize this shit in the inspector //
|
||||
GameObject textbox = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Textbox"));
|
||||
|
|
@ -177,6 +177,9 @@ namespace HeavenStudio
|
|||
}
|
||||
|
||||
SortEventsList();
|
||||
Conductor.instance.SetBpm(Beatmap.TempoChanges[0]["tempo"]);
|
||||
Conductor.instance.SetVolume(Beatmap.VolumeChanges[0]["volume"]);
|
||||
Conductor.instance.firstBeatOffset = Beatmap.data.offset;
|
||||
|
||||
if (Beatmap.Entities.Count >= 1)
|
||||
{
|
||||
|
|
@ -231,6 +234,7 @@ namespace HeavenStudio
|
|||
|
||||
public void NewRemix()
|
||||
{
|
||||
Debug.Log("Creating new remix");
|
||||
AudioLoadDone = false;
|
||||
Beatmap = new("1", "HeavenStudio");
|
||||
Beatmap.data.properties = Minigames.propertiesModel;
|
||||
|
|
@ -238,7 +242,6 @@ namespace HeavenStudio
|
|||
Beatmap.AddNewVolumeChange(0, 100f);
|
||||
Beatmap.data.offset = 0f;
|
||||
Conductor.instance.musicSource.clip = null;
|
||||
RiqFileHandler.UnlockCache();
|
||||
RiqFileHandler.WriteRiq(Beatmap);
|
||||
AudioLoadDone = true;
|
||||
}
|
||||
|
|
@ -680,6 +683,11 @@ namespace HeavenStudio
|
|||
Minigame miniGame = currentGameO?.GetComponent<Minigame>();
|
||||
if (miniGame != null)
|
||||
miniGame.OnPlay(beat);
|
||||
onPlay?.Invoke(beat);
|
||||
}
|
||||
else
|
||||
{
|
||||
onUnPause?.Invoke(beat);
|
||||
}
|
||||
|
||||
if (playMode)
|
||||
|
|
@ -693,17 +701,21 @@ namespace HeavenStudio
|
|||
public void Pause()
|
||||
{
|
||||
Conductor.instance.Pause();
|
||||
// Util.SoundByte.PauseOneShots();
|
||||
Util.SoundByte.PauseOneShots();
|
||||
onPause?.Invoke(Conductor.instance.songPositionInBeatsAsDouble);
|
||||
canInput = false;
|
||||
}
|
||||
|
||||
public void Stop(double beat, bool restart = false, float restartDelay = 0f)
|
||||
{
|
||||
// I feel like I should standardize the names
|
||||
SkillStarManager.instance.KillStar();
|
||||
TimingAccuracyDisplay.instance.StopStarFlash();
|
||||
GoForAPerfect.instance.Disable();
|
||||
SectionMedalsManager.instance.OnRemixEnd(endBeat, currentSection);
|
||||
if (Conductor.instance.isPlaying)
|
||||
{
|
||||
SkillStarManager.instance.KillStar();
|
||||
TimingAccuracyDisplay.instance.StopStarFlash();
|
||||
GoForAPerfect.instance.Disable();
|
||||
SectionMedalsManager.instance.OnRemixEnd(endBeat, currentSection);
|
||||
}
|
||||
|
||||
Minigame miniGame = currentGameO.GetComponent<Minigame>();
|
||||
if (miniGame != null)
|
||||
|
|
@ -739,22 +751,27 @@ namespace HeavenStudio
|
|||
private IEnumerator WaitReadyAndPlayCo(double beat, float delay = 1f, bool discord = true)
|
||||
{
|
||||
WaitUntil yieldOverlays = new WaitUntil(() => OverlaysManager.OverlaysReady);
|
||||
WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && Beatmap.Entities.Count > 0);
|
||||
WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && BeatmapEntities() > 0);
|
||||
WaitUntil yieldAudio = new WaitUntil(() => AudioLoadDone || (ChartLoadError && !GlobalGameManager.IsShowingDialog));
|
||||
WaitUntil yieldGame = null;
|
||||
List<Minigames.Minigame> gamesToPreload = SeekAheadAndPreload(beat, 4f);
|
||||
Debug.Log($"Preloading {gamesToPreload.Count} games");
|
||||
if (gamesToPreload.Count > 0)
|
||||
{
|
||||
yieldGame = new WaitUntil(() => gamesToPreload.All(x => x.AssetsLoaded));
|
||||
}
|
||||
|
||||
// wait for overlays to be ready
|
||||
Debug.Log("waiting for overlays");
|
||||
yield return yieldOverlays;
|
||||
// wait for beatmap to be loaded
|
||||
Debug.Log("waiting for beatmap");
|
||||
yield return yieldBeatmap;
|
||||
//wait for audio clip to be loaded
|
||||
Debug.Log("waiting for audio");
|
||||
yield return yieldAudio;
|
||||
//wait for games to be loaded
|
||||
Debug.Log("waiting for minigames");
|
||||
if (yieldGame != null)
|
||||
yield return yieldGame;
|
||||
|
||||
|
|
|
|||
|
|
@ -414,7 +414,6 @@ namespace HeavenStudio.Editor
|
|||
{
|
||||
try
|
||||
{
|
||||
RiqFileHandler.UnlockCache();
|
||||
RiqFileHandler.WriteRiq(GameManager.instance.Beatmap);
|
||||
RiqFileHandler.PackRiq(path, true);
|
||||
Debug.Log("Packed RIQ successfully!");
|
||||
|
|
@ -465,7 +464,6 @@ namespace HeavenStudio.Editor
|
|||
|
||||
try
|
||||
{
|
||||
RiqFileHandler.UnlockCache();
|
||||
string tmpDir = RiqFileHandler.ExtractRiq(path);
|
||||
Debug.Log("Imported RIQ successfully!");
|
||||
LoadRemix();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Threading.Tasks;
|
|||
using Cysharp.Threading.Tasks;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using DG.Tweening;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
|
|
@ -32,6 +33,7 @@ namespace HeavenStudio
|
|||
public static void InitPreprocessor()
|
||||
{
|
||||
RiqBeatmap.OnUpdateBeatmap += PreProcessBeatmap;
|
||||
RiqFileHandler.AudioConverter = JukeboxAudioConverter;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> propertiesModel = new()
|
||||
|
|
@ -142,6 +144,35 @@ namespace HeavenStudio
|
|||
}
|
||||
}
|
||||
|
||||
public static string JukeboxAudioConverter(string filePath, AudioType audioType, string specificType)
|
||||
{
|
||||
if (audioType == AudioType.MPEG)
|
||||
{
|
||||
Debug.Log($"mp3 loaded, Converting {filePath} to wav...");
|
||||
// convert mp3 to wav
|
||||
// import the mp3 as an audioclip
|
||||
string url = "file://" + filePath;
|
||||
using (var www = UnityWebRequestMultimedia.GetAudioClip(url, audioType))
|
||||
{
|
||||
www.SendWebRequest();
|
||||
while (!www.isDone) { }
|
||||
if (www.result == UnityWebRequest.Result.ConnectionError)
|
||||
{
|
||||
Debug.LogError($"Could not load audio file {filePath}! Error: {www.error}");
|
||||
return filePath;
|
||||
}
|
||||
AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
Debug.Log(fileName);
|
||||
SavWav.Save("/RIQCache/" + fileName, clip, true);
|
||||
filePath = Path.Combine(Application.temporaryCachePath, "/RIQCache/" + fileName + ".wav");
|
||||
|
||||
clip = null;
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// processes an riq beatmap after it is loaded
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace HeavenStudio.Common
|
|||
public void OnRemixEnd(double beat, RiqEntity lastSection)
|
||||
{
|
||||
if (!PersistentDataManager.gameSettings.isMedalOn) return;
|
||||
if (PersistentDataManager.gameSettings.isMedalOn && isMedalsStarted)
|
||||
if (PersistentDataManager.gameSettings.isMedalOn && isMedalsStarted && lastSection != null)
|
||||
{
|
||||
GameManager.instance.DoSectionCompletion(beat, isMedalsEligible, lastSection["sectionName"], 1);
|
||||
GameObject medal = Instantiate(isMedalsEligible ? MedalOkPrefab : MedalMissPrefab, MedalsHolder.transform);
|
||||
|
|
|
|||
187
Assets/Scripts/Util/SavWav.cs
Normal file
187
Assets/Scripts/Util/SavWav.cs
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
|
||||
// Copyright (c) 2012 Calvin Rien
|
||||
// http://the.darktable.com
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty. In
|
||||
// no event will the authors be held liable for any damages arising from the use
|
||||
// of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not claim
|
||||
// that you wrote the original software. If you use this software in a product,
|
||||
// an acknowledgment in the product documentation would be appreciated but is not
|
||||
// required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
// =============================================================================
|
||||
//
|
||||
// derived from Gregorio Zanon's script
|
||||
// http://forum.unity3d.com/threads/119295-Writing-AudioListener.GetOutputData-to-wav-problem?p=806734&viewfull=1#post806734
|
||||
|
||||
//
|
||||
// Fork by R-WebsterNoble
|
||||
// Optimized! Now 20 times quicker
|
||||
// Easy to get byte[] instead of saving file
|
||||
|
||||
// Note: GetWav() with trimming returns the full buffer with a load of zeros on the end.
|
||||
// Use the length out parameter to know where the data stops.
|
||||
//
|
||||
|
||||
// RHeavenStudio
|
||||
// modified to use temporary cache path instead of persistent data path
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
public static class SavWav
|
||||
{
|
||||
private const uint HeaderSize = 44;
|
||||
private const float RescaleFactor = 32767; //to convert float to Int16
|
||||
|
||||
public static void Save(string filename, AudioClip clip, bool trim = false)
|
||||
{
|
||||
if (!filename.ToLower().EndsWith(".wav"))
|
||||
{
|
||||
filename += ".wav";
|
||||
}
|
||||
|
||||
var filepath = Path.Combine(Application.temporaryCachePath, filename);
|
||||
|
||||
// Make sure directory exists if user is saving to sub dir.
|
||||
if (!Directory.Exists(Path.GetDirectoryName(filepath)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(filepath));
|
||||
}
|
||||
|
||||
using (var fileStream = new FileStream(filepath, FileMode.Create))
|
||||
using (var writer = new BinaryWriter(fileStream))
|
||||
{
|
||||
var wav = GetWav(clip, out var length, trim);
|
||||
writer.Write(wav, 0, (int)length);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetWav(AudioClip clip, out uint length, bool trim = false)
|
||||
{
|
||||
var data = ConvertAndWrite(clip, out length, out var samples, trim);
|
||||
|
||||
WriteHeader(data, clip, length, samples);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static byte[] ConvertAndWrite(AudioClip clip, out uint length, out uint samplesAfterTrimming, bool trim)
|
||||
{
|
||||
var samples = new float[clip.samples * clip.channels];
|
||||
|
||||
clip.GetData(samples, 0);
|
||||
|
||||
var sampleCount = samples.Length;
|
||||
|
||||
var start = 0;
|
||||
var end = sampleCount - 1;
|
||||
|
||||
if (trim)
|
||||
{
|
||||
for (var i = 0; i < sampleCount; i++)
|
||||
{
|
||||
if ((short)(samples[i] * RescaleFactor) == 0)
|
||||
continue;
|
||||
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
|
||||
for (var i = sampleCount -1; i >= 0; i--)
|
||||
{
|
||||
if ((short)(samples[i] * RescaleFactor) == 0)
|
||||
continue;
|
||||
|
||||
end = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var buffer = new byte[(sampleCount * 2) + HeaderSize];
|
||||
|
||||
var p = HeaderSize;
|
||||
for (var i = start; i <= end; i++)
|
||||
{
|
||||
var value = (short) (samples[i] * RescaleFactor);
|
||||
buffer[p++] = (byte) (value >> 0);
|
||||
buffer[p++] = (byte) (value >> 8);
|
||||
}
|
||||
|
||||
length = p;
|
||||
samplesAfterTrimming = (uint) (end - start + 1);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static void AddDataToBuffer(byte[] buffer, ref uint offset, byte[] addBytes)
|
||||
{
|
||||
foreach (var b in addBytes)
|
||||
{
|
||||
buffer[offset++] = b;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteHeader(byte[] stream, AudioClip clip, uint length, uint samples)
|
||||
{
|
||||
var hz = (uint)clip.frequency;
|
||||
var channels = (ushort)clip.channels;
|
||||
|
||||
var offset = 0u;
|
||||
|
||||
var riff = Encoding.UTF8.GetBytes("RIFF");
|
||||
AddDataToBuffer(stream, ref offset, riff);
|
||||
|
||||
var chunkSize = BitConverter.GetBytes(length - 8);
|
||||
AddDataToBuffer(stream, ref offset, chunkSize);
|
||||
|
||||
var wave = Encoding.UTF8.GetBytes("WAVE");
|
||||
AddDataToBuffer(stream, ref offset, wave);
|
||||
|
||||
var fmt = Encoding.UTF8.GetBytes("fmt ");
|
||||
AddDataToBuffer(stream, ref offset, fmt);
|
||||
|
||||
var subChunk1 = BitConverter.GetBytes(16u);
|
||||
AddDataToBuffer(stream, ref offset, subChunk1);
|
||||
|
||||
const ushort two = 2;
|
||||
const ushort one = 1;
|
||||
|
||||
var audioFormat = BitConverter.GetBytes(one);
|
||||
AddDataToBuffer(stream, ref offset, audioFormat);
|
||||
|
||||
var numChannels = BitConverter.GetBytes(channels);
|
||||
AddDataToBuffer(stream, ref offset, numChannels);
|
||||
|
||||
var sampleRate = BitConverter.GetBytes(hz);
|
||||
AddDataToBuffer(stream, ref offset, sampleRate);
|
||||
|
||||
var byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2
|
||||
AddDataToBuffer(stream, ref offset, byteRate);
|
||||
|
||||
var blockAlign = (ushort)(channels * 2);
|
||||
AddDataToBuffer(stream, ref offset, BitConverter.GetBytes(blockAlign));
|
||||
|
||||
ushort bps = 16;
|
||||
var bitsPerSample = BitConverter.GetBytes(bps);
|
||||
AddDataToBuffer(stream, ref offset, bitsPerSample);
|
||||
|
||||
var dataString = Encoding.UTF8.GetBytes("data");
|
||||
AddDataToBuffer(stream, ref offset, dataString);
|
||||
|
||||
var subChunk2 = BitConverter.GetBytes(samples * 2);
|
||||
AddDataToBuffer(stream, ref offset, subChunk2);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Util/SavWav.cs.meta
Normal file
11
Assets/Scripts/Util/SavWav.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a24cd489c15c51408c78bb5c145360e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
"com.unity.nuget.newtonsoft-json": "3.2.1",
|
||||
"jillejr.newtonsoft.json-for-unity.converters": "1.5.1"
|
||||
},
|
||||
"hash": "33fa051b5a6954a365df23038085caca9a844cab"
|
||||
"hash": "4628637dd95ff16553a55e0cdb08f6c4fbce2906"
|
||||
},
|
||||
"com.sr4dev.unity-spriteassist": {
|
||||
"version": "https://github.com/sr4dev/Unity-SpriteAssist.git?path=Assets/SpriteAssist",
|
||||
|
|
|
|||
Loading…
Reference in a new issue