Skip to content

Instantly share code, notes, and snippets.

@EusthEnoptEron
Last active January 14, 2021 01:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EusthEnoptEron/03cc5a701ca4fdc8ae57 to your computer and use it in GitHub Desktop.
Save EusthEnoptEron/03cc5a701ca4fdc8ae57 to your computer and use it in GitHub Desktop.
Allows streaming of all popular file formats to Unity using CSCore.
using UnityEngine;
using CSCore.Codecs;
using CSCore;
using CSCore.Streams.SampleConverter;
using System;
/// <summary>
/// AudioClip wrapper that uses the CSCore library to stream audio files into Unity's AudioClips.
/// </summary>
public class CSCAudioClip : IDisposable
{
private string m_name;
private IWaveSource m_source;
private WaveToSampleBase m_decoder;
private bool m_disposed = false;
/// <summary>
/// Gets the AudioClip that belongs to this CSCAudioClip.
/// </summary>
public AudioClip Clip { get; private set; }
/// <summary>
/// Creates a new CSCAudioClip from a network resource.
/// </summary>
/// <param name="uri"></param>
public CSCAudioClip(Uri uri)
{
m_source = CodecFactory.Instance.GetCodec(uri);
m_name = uri.AbsoluteUri;
Initialize();
}
/// <summary>
/// Creates a new CSCAudioClip from a local file.
/// </summary>
/// <param name="filename"></param>
public CSCAudioClip(string filename)
{
m_source = CodecFactory.Instance.GetCodec(filename);
m_name = filename;
Initialize();
}
private void Initialize()
{
switch (m_source.WaveFormat.BitsPerSample)
{
case 8:
m_decoder = new Pcm8BitToSample(m_source);
break;
case 16:
m_decoder = new Pcm16BitToSample(m_source);
break;
case 24:
m_decoder = new Pcm24BitToSample(m_source);
break;
default:
Debug.LogError("No converter found!");
return;
}
Clip = AudioClip.Create(m_name,
(int)(m_decoder.Length / m_decoder.WaveFormat.Channels),
m_decoder.WaveFormat.Channels,
m_decoder.WaveFormat.SampleRate,
true,
OnReadAudio,
OnSetPosition);
}
private void OnReadAudio(float[] data)
{
if (m_disposed) return;
//Debug.LogFormat("Load Data: {0}", data.Length);
m_decoder.Read(data, 0, data.Length);
}
private void OnSetPosition(int position)
{
if (m_disposed) return;
//Debug.LogFormat("Set Position: {0}", position);
m_decoder.Position = position * m_decoder.WaveFormat.Channels;
}
/// <summary>
/// Frees resources taken by CSCore.
/// </summary>
public void Dispose()
{
if (!m_disposed)
{
m_decoder.Dispose();
m_source.Dispose();
m_disposed = true;
}
}
}
@yura415
Copy link

yura415 commented Nov 5, 2015

Hi @EusthEnoptEron, how you managed to include CSCore into your Unity project?

Oh, I've needed to set Api Compatability Level to ".NET 2.0" in Player Settings in order for this to compile.
But CSCore works only on Windows 😢 (missing mfplat.dll)

@yura415
Copy link

yura415 commented Nov 5, 2015

Planning to implement Ogg Vorbis streaming with csvorbis and TcpClient.

@lparkermg
Copy link

This is just what I need, thanks for sharing. Like with @yura415 cscore seems to not work in osx.

@kuochiyoug
Copy link

Is it possible to do it like the realtime audio streaming clip with the loopback shows in following codes??
https://github.com/hallidev/UnityWASAPILoopbackAudio

@ZeoWorks
Copy link

Would love to use this with WASAPILoopbackAudio also!
So we can have runtime windows audio to audioclip. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment