Skip to content

Feature/audio processor #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 16 additions & 25 deletions Assets/Plugins/RetroUnity/Scripts/LibretroWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ public class Environment {
}

public class Wrapper {
public const int AudioBatchSize = 4096;
public static List<float> AudioBatch = new List<float>(65536);
public static int BatchPosition;
private PixelFormat _pixelFormat;
private bool _requiresFullPath;
private SystemAVInfo _av;
Expand Down Expand Up @@ -327,30 +324,24 @@ private unsafe void RetroVideoRefresh(void* data, uint width, uint height, uint
}

private void RetroAudioSample(short left, short right) {
// Unused.
float[] floatBuffer = {
Mathf.Clamp(left * -0.000030517578125f, -1.0f, 1.0f),
Mathf.Clamp(right * -0.000030517578125f, -1.0f, 1.0f)
};

_speaker.ProcessSamples(floatBuffer);
}

private unsafe void RetroAudioSampleBatch(short* data, uint frames) {
//for (int i = 0; i < (int) frames; i++) {
// short chunk = Marshal.ReadInt16((IntPtr) data);
// data += sizeof (short); // Set pointer to next chunk.
// float value = chunk / 32768f; // Divide by Int16 max to get correct float value.
// value = Mathf.Clamp(value, -1.0f, 1.0f); // Unity's audio only takes values between -1 and 1.

// AudioBatch[BatchPosition] = value;
// BatchPosition++;

// // When the batch is filled send it to the speakers.
// if (BatchPosition >= AudioBatchSize - 1) {
// _speaker.UpdateAudio(AudioBatch);
// BatchPosition = 0;
// }
//}
for (int i = 0; i < frames * 2; ++i) {
float value = data[i] * 0.000030517578125f;
value = Mathf.Clamp(value, -1.0f, 1.0f); // Unity's audio only takes values between -1 and 1.
AudioBatch.Add(value);
private unsafe uint RetroAudioSampleBatch(short* data, uint frames) {
var floatBuffer = new float[frames * 2];

for (var i = 0; i < floatBuffer.Length; ++i)
{
floatBuffer[i] = Mathf.Clamp(data[i] * 0.000030517578125f, -1.0f, 1.0f);
}

_speaker.ProcessSamples(floatBuffer);
return frames;
}

private void RetroInputPoll() {
Expand Down Expand Up @@ -560,7 +551,7 @@ public unsafe class Libretro {
public delegate void RetroAudioSampleDelegate(short left, short right);

//typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames);
public delegate void RetroAudioSampleBatchDelegate(short* data, uint frames);
public delegate uint RetroAudioSampleBatchDelegate(short* data, uint frames);

//typedef void (*retro_input_poll_t)(void);
public delegate void RetroInputPollDelegate();
Expand Down
34 changes: 18 additions & 16 deletions Assets/Plugins/RetroUnity/Scripts/Speaker.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace RetroUnity {
[RequireComponent(typeof(AudioSource))]
public class Speaker : MonoBehaviour {

public const int AudioBatchSize = 65536;
public static List<float> AudioBatch = new List<float>(AudioBatchSize);

private AudioSource _speaker;

private void Start() {
_speaker = GetComponent<AudioSource>();
if (_speaker == null) return;
//var audioConfig = AudioSettings.GetConfiguration();
//audioConfig.sampleRate = 32000;
//AudioSettings.Reset(audioConfig);
//AudioClip clip = AudioClip.Create("Libretro", LibretroWrapper.Wrapper.AudioBatchSize / 2, 2, 44100, true, OnAudioRead);
//AudioClip clip = AudioClip.Create("Libretro", 256, 2, 32000, true);
//_speaker.clip = clip;
_speaker.Play();
//_speaker.loop = true;
//Debug.Log("Unity sample rate: " + audioConfig.sampleRate);
//Debug.Log("Unity buffer size: " + audioConfig.dspBufferSize);
}

private void OnAudioFilterRead(float[] data, int channels) {
// wait until enough data is available
if (LibretroWrapper.Wrapper.AudioBatch.Count < data.Length)
if (AudioBatch.Count < data.Length)
return;
int i;
for (i = 0; i < data.Length; i++)
data[i] = LibretroWrapper.Wrapper.AudioBatch[i];
for (var i = 0; i < data.Length; i++)
data[i] = AudioBatch[i];
// remove data from the beginning
LibretroWrapper.Wrapper.AudioBatch.RemoveRange(0, i);
AudioBatch.RemoveRange(0, data.Length);
}

public void ProcessSamples(float[] samples)
{
foreach (var value in samples)
{
AudioBatch.Add(value);
}
}


private void OnGUI() {
GUI.Label(new Rect(0f, 0f, 300f, 20f), LibretroWrapper.Wrapper.AudioBatch.Count.ToString());
GUI.Label(new Rect(0f, 0f, 300f, 20f), AudioBatch.Count.ToString());
}
}
}