📅  最后修改于: 2023-12-03 15:20:52.430000             🧑  作者: Mango
Unity SoundClip Mix is a C# program that allows you to mix multiple audio clips into a single audio clip in Unity. This program is useful for creating background music or sound effects for your games or applications.
To use Unity SoundClip Mix, simply attach the SoundClipMix script to an empty GameObject in your Unity scene. Then, drag and drop the audio clips you want to mix into the AudioClip array in the inspector.
To adjust the volume of each clip, use the Volume array in the inspector to set the volume of each clip. The values in the Volume array should correspond to the order of the audio clips in the AudioClip array.
Once you have added your audio clips and adjusted the volumes, press the Mix button in the inspector to mix the audio clips into a single audio clip. The mixed audio clip will be saved as a .wav file in the root directory of your Unity project.
using UnityEngine;
using System.IO;
public class SoundClipMix : MonoBehaviour
{
public AudioClip[] AudioClip; //Array to hold audio clips
public float[] Volume; //Array to hold volume for each clip
[SerializeField] private string _fileName = "MixedAudioClip"; //Name of exported file
private void Start()
{
Mix();
}
private void Mix()
{
if (AudioClip.Length == 0) return;
int length = AudioClip[0].samples; //Get sample length of first clip
int numChannels = AudioClip[0].channels; //Get number of channels of first clip
//Get sample length of longest clip
for (int i = 1; i < AudioClip.Length; i++)
{
if (AudioClip[i].samples > length)
{
length = AudioClip[i].samples;
}
}
//Create float arrays to hold samples of each clip
float[][] samples = new float[AudioClip.Length][];
for (int i = 0; i < AudioClip.Length; i++)
{
samples[i] = new float[length * numChannels];
}
//Get samples from each clip and adjust volume
for (int i = 0; i < AudioClip.Length; i++)
{
float[] tmpSamples = new float[AudioClip[i].samples * numChannels];
AudioClip[i].GetData(tmpSamples, 0);
for (int j = 0; j < tmpSamples.Length; j++)
{
samples[i][j] = tmpSamples[j] * Volume[i];
}
}
//Mix samples together
float[] mixedSamples = new float[length * numChannels];
for (int i = 0; i < length * numChannels; i++)
{
float sum = 0f;
for (int j = 0; j < samples.Length; j++)
{
if (i < samples[j].Length) sum += samples[j][i];
}
mixedSamples[i] = sum;
}
//Create new audio clip with mixed samples
AudioClip mixedClip = AudioClip.Create(_fileName,
length,
numChannels,
AudioClip[0].frequency,
false);
mixedClip.SetData(mixedSamples, 0);
//Export mixed audio clip as .wav file
using (FileStream fileStream = CreateEmpty(_fileName))
{
ConvertAndWrite(fileStream, mixedClip);
WriteHeader(fileStream, mixedClip);
}
}
//Helper function to create empty .wav file
private FileStream CreateEmpty(string filepath)
{
FileStream fileStream = new FileStream(filepath + ".wav", FileMode.Create);
byte emptyByte = new byte();
for (int i = 0; i < 44; i++) //Write header
{
fileStream.WriteByte(emptyByte);
}
return fileStream;
}
//Helper function to convert audio clip to byte array
private void ConvertAndWrite(FileStream fileStream, AudioClip clip)
{
float[] samples = new float[clip.samples];
clip.GetData(samples, 0);
Int16[] intData = new Int16[samples.Length];
Byte[] bytesData = new Byte[samples.Length * 2];
for (int i = 0; i < samples.Length; i++)
{
intData[i] = (short)(samples[i] * 32767f);
Byte[] byteArr = new Byte[2];
byteArr = BitConverter.GetBytes(intData[i]);
byteArr.CopyTo(bytesData, i * 2);
}
fileStream.Write(bytesData, 0, bytesData.Length);
}
//Helper function to write .wav header
private void WriteHeader(FileStream fileStream, AudioClip clip)
{
int hz = clip.frequency;
int channels = clip.channels;
int samples = clip.samples;
fileStream.Seek(0, SeekOrigin.Begin);
Byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF");
fileStream.Write(riff, 0, 4);
Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8);
fileStream.Write(chunkSize, 0, 4);
Byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE");
fileStream.Write(wave, 0, 4);
Byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt ");
fileStream.Write(fmt, 0, 4);
Byte[] subChunk1 = BitConverter.GetBytes(16);
fileStream.Write(subChunk1, 0, 4);
UInt16 one = 1;
Byte[] audioFormat = BitConverter.GetBytes(one);
fileStream.Write(audioFormat, 0, 2);
Byte[] numChannels = BitConverter.GetBytes(channels);
fileStream.Write(numChannels, 0, 2);
Byte[] sampleRate = BitConverter.GetBytes(hz);
fileStream.Write(sampleRate, 0, 4);
Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels
fileStream.Write(byteRate, 0, 4);
UInt16 blockAlign = (ushort)(channels * 2);
fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2);
UInt16 bps = 16;
Byte[] bitsPerSample = BitConverter.GetBytes(bps);
fileStream.Write(bitsPerSample, 0, 2);
Byte[] data = System.Text.Encoding.UTF8.GetBytes("data");
fileStream.Write(data, 0, 4);
Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
fileStream.Write(subChunk2, 0, 4);
}
}
Unity SoundClip Mix is a simple yet powerful tool for mixing audio clips in Unity. With its easy-to-use interface and flexible features, you can create high quality background music and sound effects for your games and applications.