FFT Selection
This commit is contained in:
parent
a04dbcc5d5
commit
d6059d5104
7 changed files with 69 additions and 55 deletions
|
@ -18,7 +18,7 @@ namespace cylvester
|
||||||
public void OnEnable()
|
public void OnEnable()
|
||||||
{
|
{
|
||||||
spectrumGenerator_ = new SpectrumGenerator(TextureWidth, TextureHeight);
|
spectrumGenerator_ = new SpectrumGenerator(TextureWidth, TextureHeight);
|
||||||
rectangularSelection_ = new RectangularSelection(ref paintSpace_, TextureWidth, TextureHeight);
|
rectangularSelection_ = new RectangularSelection(TextureWidth, TextureHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
public override void OnInspectorGUI()
|
||||||
|
@ -36,7 +36,7 @@ namespace cylvester
|
||||||
}
|
}
|
||||||
case EventType.MouseDrag:
|
case EventType.MouseDrag:
|
||||||
{
|
{
|
||||||
rectangularSelection_.Update(Event.current.mousePosition);
|
rectangularSelection_.Update(Event.current.mousePosition, ref paintSpace_);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,15 @@ namespace cylvester
|
||||||
{
|
{
|
||||||
paintSpace_ = paintSpace;
|
paintSpace_ = paintSpace;
|
||||||
behaviour.PdArray.Update();
|
behaviour.PdArray.Update();
|
||||||
spectrumGenerator_.Update(behaviour.PdArray.Data, ref rectangularSelection_.Selection);
|
behaviour.Energy = spectrumGenerator_.Update(behaviour.PdArray.Data, ref rectangularSelection_.Selection);
|
||||||
GUI.DrawTexture(paintSpace_, spectrumGenerator_.Spectrum);
|
GUI.DrawTexture(paintSpace_, spectrumGenerator_.Spectrum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Extracted Energy", EditorStyles.boldLabel);
|
||||||
|
GUILayout.Label(behaviour.Energy.ToString());
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace cylvester
|
||||||
ref Rect Selection { get; }
|
ref Rect Selection { get; }
|
||||||
|
|
||||||
void Start(Vector2 mousePosition);
|
void Start(Vector2 mousePosition);
|
||||||
void Update(Vector2 mousePosition);
|
void Update(Vector2 mousePosition, ref Rect paintSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RectangularSelection : IRectangularSelection
|
public class RectangularSelection : IRectangularSelection
|
||||||
|
@ -21,9 +21,8 @@ namespace cylvester
|
||||||
|
|
||||||
public ref Rect Selection => ref selectionRect_;
|
public ref Rect Selection => ref selectionRect_;
|
||||||
|
|
||||||
public RectangularSelection(ref Rect paintSpace, int textureWidth, int textureHeight)
|
public RectangularSelection(int textureWidth, int textureHeight)
|
||||||
{
|
{
|
||||||
paintSpace_ = paintSpace;
|
|
||||||
textureWidth_ = textureWidth;
|
textureWidth_ = textureWidth;
|
||||||
textureHeight_ = textureHeight;
|
textureHeight_ = textureHeight;
|
||||||
}
|
}
|
||||||
|
@ -34,14 +33,14 @@ namespace cylvester
|
||||||
selectedArea_.y = mousePosition.y;
|
selectedArea_.y = mousePosition.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(Vector2 mousePosition)
|
public void Update(Vector2 mousePosition, ref Rect paintSpace)
|
||||||
{
|
{
|
||||||
selectedArea_.width = mousePosition.x - selectedArea_.x;
|
selectedArea_.width = mousePosition.x - selectedArea_.x;
|
||||||
selectedArea_.height = mousePosition.y - selectedArea_.y;
|
selectedArea_.height = mousePosition.y - selectedArea_.y;
|
||||||
var xPos = (selectedArea_.x - paintSpace_.x) / paintSpace_.width;
|
var xPos = (selectedArea_.x - paintSpace.x) / paintSpace.width;
|
||||||
var yPos = (selectedArea_.y - paintSpace_.y) / paintSpace_.height;
|
var yPos = (selectedArea_.y - paintSpace.y) / paintSpace.height;
|
||||||
var width = selectedArea_.width / paintSpace_.width;
|
var width = selectedArea_.width / paintSpace.width;
|
||||||
var height = selectedArea_.height / paintSpace_.height;
|
var height = selectedArea_.height / paintSpace.height;
|
||||||
|
|
||||||
selectionRect_.x = xPos * textureWidth_;
|
selectionRect_.x = xPos * textureWidth_;
|
||||||
selectionRect_.y = yPos * textureHeight_;
|
selectionRect_.y = yPos * textureHeight_;
|
||||||
|
|
|
@ -5,42 +5,47 @@ namespace cylvester
|
||||||
interface ISpectrumGenerator
|
interface ISpectrumGenerator
|
||||||
{
|
{
|
||||||
Texture2D Spectrum { get; }
|
Texture2D Spectrum { get; }
|
||||||
void Update(float[] fftData, ref Rect selectionRect);
|
int Update(float[] fftData, ref Rect selectionRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SpectrumGenerator : ISpectrumGenerator
|
public class SpectrumGenerator : ISpectrumGenerator
|
||||||
{
|
{
|
||||||
private Texture2D texture_;
|
private Texture2D texture_;
|
||||||
private readonly int height_;
|
|
||||||
public Texture2D Spectrum => texture_;
|
public Texture2D Spectrum => texture_;
|
||||||
|
|
||||||
public SpectrumGenerator(int width, int height)
|
public SpectrumGenerator(int width, int height)
|
||||||
{
|
{
|
||||||
texture_ = new Texture2D(width, height);
|
texture_ = new Texture2D(width, height);
|
||||||
height_ = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(float[] fftData, ref Rect selectionRect)
|
public int Update(float[] fftData, ref Rect selectionRect)
|
||||||
{
|
{
|
||||||
|
var numPixels = 0;
|
||||||
for (var x = 0; x < texture_.width; x++)
|
for (var x = 0; x < texture_.width; x++)
|
||||||
{
|
{
|
||||||
var magnitude = fftData[x];
|
var magnitude = fftData[x] * 20f;
|
||||||
for (var y = 0; y < texture_.height; y++)
|
for (var y = 0; y < texture_.height; y++)
|
||||||
{
|
{
|
||||||
|
var mY = texture_.height - selectionRect.y;
|
||||||
|
|
||||||
var alpha = 0.4f;
|
var fillPixel = magnitude > y;
|
||||||
|
var color = fillPixel ? Color.green : Color.black;
|
||||||
if ((selectionRect.x < x && x < (selectionRect.x + selectionRect.width)) &&
|
if ((selectionRect.x < x && x < (selectionRect.x + selectionRect.width)) &&
|
||||||
(selectionRect.y < y && y < (selectionRect.y + selectionRect.height)))
|
(mY - selectionRect.height < y && y < mY))
|
||||||
{
|
{
|
||||||
alpha = 1f;
|
color.a = 1f;
|
||||||
|
if (fillPixel)
|
||||||
|
numPixels++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
var color = y > magnitude ? Color.white : Color.gray;
|
{
|
||||||
color.a = alpha;
|
color.a = 0.2f;
|
||||||
texture_.SetPixel(x, height_, color);
|
}
|
||||||
|
texture_.SetPixel(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
texture_.Apply();
|
texture_.Apply();
|
||||||
|
return numPixels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -280,7 +280,6 @@ GameObject:
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 987772534}
|
- component: {fileID: 987772534}
|
||||||
- component: {fileID: 987772533}
|
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: PdBackend
|
m_Name: PdBackend
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
|
@ -288,20 +287,6 @@ GameObject:
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
m_IsActive: 1
|
m_IsActive: 1
|
||||||
--- !u!114 &987772533
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 987772532}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 3ba69cee3466a304d9d570268f717413, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
mainPatch: analyzer.pd
|
|
||||||
inchannels: 2
|
|
||||||
--- !u!4 &987772534
|
--- !u!4 &987772534
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
@ -50,7 +50,6 @@ namespace cylvester
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
PdProcess.Instance.Start(mainPatch, inchannels);
|
PdProcess.Instance.Start(mainPatch, inchannels);
|
||||||
Thread.Sleep(500);
|
|
||||||
|
|
||||||
levelMeterArray_ = new PdArray("levelmeters", NumMaxInputChannels);
|
levelMeterArray_ = new PdArray("levelmeters", NumMaxInputChannels);
|
||||||
udpSender_ = new UdpSender("127.0.0.1", 54637);
|
udpSender_ = new UdpSender("127.0.0.1", 54637);
|
||||||
|
@ -65,11 +64,8 @@ namespace cylvester
|
||||||
|
|
||||||
public void UpdateShmem()
|
public void UpdateShmem()
|
||||||
{
|
{
|
||||||
levelMeterArray_.Update();
|
if(PdProcess.Instance.Running)
|
||||||
|
levelMeterArray_.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Debug = UnityEngine.Debug;
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ namespace cylvester
|
||||||
{
|
{
|
||||||
void Start(string mainPatch, int numInputChannels);
|
void Start(string mainPatch, int numInputChannels);
|
||||||
void Stop();
|
void Stop();
|
||||||
|
bool Running { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PdProcess : IPdProcess
|
public class PdProcess : IPdProcess
|
||||||
|
@ -25,8 +27,13 @@ namespace cylvester
|
||||||
|
|
||||||
public void Start(string mainPatch, int numInputChannels)
|
public void Start(string mainPatch, int numInputChannels)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (pdProcess_ != null)
|
if (pdProcess_ != null)
|
||||||
return;
|
{
|
||||||
|
pdProcess_.Refresh();
|
||||||
|
if (!pdProcess_.HasExited)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pdProcess_ = new Process();
|
pdProcess_ = new Process();
|
||||||
pdProcess_.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
pdProcess_.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||||
|
@ -40,14 +47,33 @@ namespace cylvester
|
||||||
{
|
{
|
||||||
throw new Exception("Pd process failed to start");
|
throw new Exception("Pd process failed to start");
|
||||||
}
|
}
|
||||||
|
Thread.Sleep(500);
|
||||||
Debug.Log("Pd Process started");
|
Debug.Log("Pd Process started");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
pdProcess_?.Kill();
|
if (pdProcess_ == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pdProcess_.Kill();
|
||||||
pdProcess_ = null;
|
pdProcess_ = null;
|
||||||
Debug.Log("Pd Process stopped");
|
Debug.Log("Pd Process stopped");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Running
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
pdProcess_.Refresh();
|
||||||
|
if (pdProcess_ == null)
|
||||||
|
return false;
|
||||||
|
if (pdProcess_.HasExited)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ namespace cylvester
|
||||||
public interface IPdSpectrumBind
|
public interface IPdSpectrumBind
|
||||||
{
|
{
|
||||||
IPdArray PdArray { get; }
|
IPdArray PdArray { get; }
|
||||||
float TrimmedEnergy { get; }
|
int Energy { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[ExecuteInEditMode]
|
[ExecuteInEditMode]
|
||||||
|
@ -16,18 +16,16 @@ namespace cylvester
|
||||||
public int endBin;
|
public int endBin;
|
||||||
public float topClip;
|
public float topClip;
|
||||||
public float bottomClip;
|
public float bottomClip;
|
||||||
public float trimmedEnergy = 0f;
|
|
||||||
|
|
||||||
public float TrimmedEnergy => trimmedEnergy;
|
|
||||||
|
|
||||||
private PdArray pdArray_;
|
private PdArray pdArray_;
|
||||||
public IPdArray PdArray => pdArray_;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
pdArray_ = new PdArray("fft_" + channel, 512);
|
pdArray_ = new PdArray("fft_" + channel, 512);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IPdArray PdArray => pdArray_;
|
||||||
|
|
||||||
|
public int Energy { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue