поэтому я работаю над программой определения порогов слышимости людей. Поэтому мне нужно играть на разных частотах и измерять время отклика субъекта. Чтобы измерить время отклика, я использую несколько секундомеров в своем коде. Один из них запускается после того, как я использую метод play () моего объекта AsioOut, и останавливается, когда субъект нажимает кнопку ввода. Но время, казалось, не сработало. При дальнейших исследованиях с помощью осциллографа я мог бы сказать, что это остаток предыдущего воспроизводимого сигнала, и есть задержка до воспроизведения действительного сигнала, что, как я подозреваю, является причиной моей проблемы.
Я полагаю в буфере моего плеера все еще есть некоторые вещи, которые воспроизводятся по моему новому сигналу, но я не знаю, как от этого избавиться. В Интернете я нашел кого-то с такой же проблемой, и решение его проблемы состояло в том, чтобы вызвать метод Stop () его проигрывателя, который очистит буфер. Я попробовал этот подход без успеха. Эти биты все еще воспроизводятся.
public class SineWaveProvider32 : WaveProvider32
{
public static float length;
public static float tRamp;
public static int fSamp;
public static float[] Env; //Envelope on signal to create ramps
public static int nSamp;
public static int nRampsamples;
public static float[] tSamp;
public static float tSingleSamp;
public static Boolean stopRepeat = false;
private Boolean repeat;
private float Frequency;
private int sample;
public SineWaveProvider32(float frequency, Boolean repeat)
{
this.Frequency = frequency;
this.repeat = repeat;
SetWaveFormat(fSamp, 1);
}
public override int Read(float[] buffer, int offset, int sampleCount)
{
int sampleRate = fSamp;
offset = 0;
if (!repeat) {
for (int n = 0; n < sampleCount; n++) {
buffer[n + offset] = (float)(Env[sample] * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));
sample++;
if (sample == Env.Length - 1) {
sampleCount = 0;
sample = 0;
n = 0;
break;
}
}
} else {
for (int n = 0; n < sampleCount; n++) {
buffer[n + offset] = (float)(Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));
sample++;
if (sample >= sampleRate) sample = 0;
if (stopRepeat)
{
sampleCount = 0;
break;
}
}
return sampleCount;
}
return sampleCount;
}
public static void Initialise(int Samplerate, float Length, float Ramps) {
fSamp = Samplerate;
length = Length;
tRamp = Ramps;
nRampsamples = (int)(tRamp * fSamp);
tSamp = new float[(int)(length * fSamp)];
tSamp[0] = 0.0f;
for (int i = 1; i < tSamp.Length; i++) {
tSamp[i] = (float)(tSamp[i - 1] + (1.0f / fSamp));
}
nSamp = (int)(length * fSamp);
Env = new float[nSamp];
for (int n = 0; n < nRampsamples; n++) {
Env[n] = (float)(0.5 * (1 - Math.Cos(Math.PI * tSamp[n] / (tRamp)))); // starting ramp
}
for (int n = nRampsamples; n < nSamp - nRampsamples; n++) {
Env[n] = 1.0f;
}
for (int n = nSamp - 1; n >= nSamp - nRampsamples; n--) {
Env[n] = (float)(0.5 * (1 - Math.Cos(Math.PI * tSamp[0 - (n - (nSamp - 1))] / (tRamp)))); // ending ramp
}
}
}
Это мой класс SineWaveProvider32, может быть, я что-то напутал.
Также предоставлены две картинки. Один из них ясно показывает короткий фрагмент синусоидальной волны 8 кГц, который ранее воспроизводился до синусоиды 1 кГц. На другом рисунке показан небольшой фрагмент предыдущей синусоиды 1 кГц, включая линейные изменения, воспроизводимые непосредственно перед фактическим сигналом. Синие пики указывают на нажатие / отпускание кнопки ввода. В идеальном мире моя программа показывает время между стартовым сигналом и первым синим понижением. Но это всегда показывает многое. Надеюсь, я смогу объяснить достаточно, и что есть кто-то, кто мог бы помочь мне:)
https://i.stack.imgur.com/TeaL3.jpg
https://i.stack.imgur.com/FOI53.jpg