如何在从 'ISampleSource' 中读取样本数组后回放样本数组
How to play back a array of samples after reading them from an 'ISampleSource'
所以,我有一段代码将 ISampleSource
读出到 float[][]
,第一个数组层用于通道数,第二个用于通道内的样本数据这个频道。我将获取这些数据并尝试对其应用信号处理,但是出于调试目的,我可能想要操作示例数组然后播放它以便我可以 "hear" 代码正在做什么。有没有一种简单的方法来获取 ISampleSource.Read
返回的数据并将其粘贴回 new ISampleSource
以便可以将其转换为 IWaveSource
并使用 WasapiOut
?
播放
这是我到目前为止尝试制作的 class,你将它传递给 float[][]
并且基本上所有数据都在 WaveFormat
中,以便它制作一个......但是它实际上并没有做 任何事情。没有错误,没有播放.. 什么都不做。我做错了什么?
private class SampleSource : ISampleSource
{
public long Position { get; set; }
public WaveFormat WaveFormat { get; private set; }
public bool CanSeek => true;
public long Length => _data.Length;
private float[] _data;
private long readPoint = 0;
public SampleSource(float[][] samples, int sampleRate, int bits, int channels)
{
WaveFormat = new WaveFormat(sampleRate, bits, channels);
if (samples.Length <= 0) return;
_data = new float[samples[0].Length * samples.Length];
int cchannels = samples.Length;
int sampleLength = samples[0].Length;
for (var i = 0; i < sampleLength; i += cchannels)
for (var n = 0; n < cchannels; n++)
_data[i + n] = samples[n][i / cchannels];
}
public int Read(float[] buffer, int offset, int count)
{
if (_data.Length < Position + count)
count = (int) (_data.Length - Position);
float[] outFloats = new float[count];
for (var i = 0; i < count; i++)
outFloats[i] = _data[i + Position + offset];
buffer = outFloats;
Position += count;
return count;
}
public void Dispose() =>_data = null;
}
而不是尝试将 buffer
设置为新数组(这毫无意义)我需要直接写入 buffer
数组元素,以便它们可以在函数之外使用称呼。我真的不 喜欢 这样做,也许是为了解决我没有看到的问题,但显然这就是我使用的库的方式。
private class SampleSource : ISampleSource
{
public long Position { get; set; }
public WaveFormat WaveFormat { get; private set; }
public bool CanSeek => true;
public long Length => _data.Length;
private float[] _data;
private long readPoint = 0;
public SampleSource(float[][] samples, int sampleRate, int bits, int channels)
{
WaveFormat = new WaveFormat(sampleRate, bits, channels);
if (samples.Length <= 0) return;
_data = new float[samples[0].Length * samples.Length];
int cchannels = samples.Length;
int sampleLength = samples[0].Length;
for (var i = 0; i < sampleLength; i += cchannels)
for (var n = 0; n < cchannels; n++)
_data[i + n] = samples[n][i / cchannels];
}
public int Read(float[] buffer, int offset, int count)
{
/*THIS IS THE CHANGED FUNCTION*/
if (_data.Length < Position + count)
count = (int) (_data.Length - Position);
for (var i = 0; i < count; i++)
buffer[i] = _data[i + Position + offset];
Position += count;
return count;
}
public void Dispose() =>_data = null;
}
所以,我有一段代码将 ISampleSource
读出到 float[][]
,第一个数组层用于通道数,第二个用于通道内的样本数据这个频道。我将获取这些数据并尝试对其应用信号处理,但是出于调试目的,我可能想要操作示例数组然后播放它以便我可以 "hear" 代码正在做什么。有没有一种简单的方法来获取 ISampleSource.Read
返回的数据并将其粘贴回 new ISampleSource
以便可以将其转换为 IWaveSource
并使用 WasapiOut
?
这是我到目前为止尝试制作的 class,你将它传递给 float[][]
并且基本上所有数据都在 WaveFormat
中,以便它制作一个......但是它实际上并没有做 任何事情。没有错误,没有播放.. 什么都不做。我做错了什么?
private class SampleSource : ISampleSource
{
public long Position { get; set; }
public WaveFormat WaveFormat { get; private set; }
public bool CanSeek => true;
public long Length => _data.Length;
private float[] _data;
private long readPoint = 0;
public SampleSource(float[][] samples, int sampleRate, int bits, int channels)
{
WaveFormat = new WaveFormat(sampleRate, bits, channels);
if (samples.Length <= 0) return;
_data = new float[samples[0].Length * samples.Length];
int cchannels = samples.Length;
int sampleLength = samples[0].Length;
for (var i = 0; i < sampleLength; i += cchannels)
for (var n = 0; n < cchannels; n++)
_data[i + n] = samples[n][i / cchannels];
}
public int Read(float[] buffer, int offset, int count)
{
if (_data.Length < Position + count)
count = (int) (_data.Length - Position);
float[] outFloats = new float[count];
for (var i = 0; i < count; i++)
outFloats[i] = _data[i + Position + offset];
buffer = outFloats;
Position += count;
return count;
}
public void Dispose() =>_data = null;
}
而不是尝试将 buffer
设置为新数组(这毫无意义)我需要直接写入 buffer
数组元素,以便它们可以在函数之外使用称呼。我真的不 喜欢 这样做,也许是为了解决我没有看到的问题,但显然这就是我使用的库的方式。
private class SampleSource : ISampleSource
{
public long Position { get; set; }
public WaveFormat WaveFormat { get; private set; }
public bool CanSeek => true;
public long Length => _data.Length;
private float[] _data;
private long readPoint = 0;
public SampleSource(float[][] samples, int sampleRate, int bits, int channels)
{
WaveFormat = new WaveFormat(sampleRate, bits, channels);
if (samples.Length <= 0) return;
_data = new float[samples[0].Length * samples.Length];
int cchannels = samples.Length;
int sampleLength = samples[0].Length;
for (var i = 0; i < sampleLength; i += cchannels)
for (var n = 0; n < cchannels; n++)
_data[i + n] = samples[n][i / cchannels];
}
public int Read(float[] buffer, int offset, int count)
{
/*THIS IS THE CHANGED FUNCTION*/
if (_data.Length < Position + count)
count = (int) (_data.Length - Position);
for (var i = 0; i < count; i++)
buffer[i] = _data[i + Position + offset];
Position += count;
return count;
}
public void Dispose() =>_data = null;
}