При воспроизведении нового сигнала воспроизводится немного старого сигнала - PullRequest
0 голосов
/ 14 января 2020

поэтому я работаю над программой определения порогов слышимости людей. Поэтому мне нужно играть на разных частотах и ​​измерять время отклика субъекта. Чтобы измерить время отклика, я использую несколько секундомеров в своем коде. Один из них запускается после того, как я использую метод 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

...