Меняю значение высоких и низких звуковых частот - C#
Формулировка задачи:
Здравствуйте!
Работаю над одним генератором звуковых частот, вернее над генератором шума. Нашёл отличную библиотеку NAudio.dll и работаю с ней. Подключил к проекту вот такой класс, в котором есть всё что мне нужно для генерации.using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WhiteNoiseGenerator
{
class SignalGenerator : ISampleProvider
{
// Wave format
private readonly WaveFormat waveFormat;
// Random Number for the White Noise & Pink Noise Generator
private readonly Random random = new Random();
private readonly double[] pinkNoiseBuffer = new double[7];
// Const Math
private const double TwoPi = 2 * Math.PI;
// Generator variable
private int nSample;
// Sweep Generator variable
private double phi;
/// <summary>
/// Initializes a new instance for the Generator (Default :: 44.1Khz, 2 channels, Sinus, Frequency = 440, Gain = 1)
/// </summary>
public SignalGenerator()
: this(44100, 2)
{
}
/// <summary>
/// Initializes a new instance for the Generator (UserDef SampleRate & Channels)
/// </summary>
/// <param name="sampleRate">Desired sample rate</param>
/// <param name="channel">Number of channels</param>
public SignalGenerator(int sampleRate, int channel)
{
phi = 0;
waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channel);
// Default
Type = SignalGeneratorType.Sin;
Frequency = 440.0;
Gain = 1;
PhaseReverse = new bool[channel];
SweepLengthSecs = 2;
}
/// <summary>
/// The waveformat of this WaveProvider (same as the source)
/// </summary>
public WaveFormat WaveFormat
{
get { return waveFormat; }
}
/// <summary>
/// Frequency for the Generator. (20.0 - 20000.0 Hz)
/// Sin, Square, Triangle, SawTooth, Sweep (Start Frequency).
/// </summary>
public double Frequency { get; set; }
/// <summary>
/// Return Log of Frequency Start (Read only)
/// </summary>
public double FrequencyLog
{
get { return Math.Log(Frequency); }
}
/// <summary>
/// End Frequency for the Sweep Generator. (Start Frequency in Frequency)
/// </summary>
public double FrequencyEnd { get; set; }
/// <summary>
/// Return Log of Frequency End (Read only)
/// </summary>
public double FrequencyEndLog
{
get { return Math.Log(FrequencyEnd); }
}
/// <summary>
/// Gain for the Generator. (0.0 to 1.0)
/// </summary>
public double Gain { get; set; }
/// <summary>
/// Channel PhaseReverse
/// </summary>
public bool[] PhaseReverse { get; private set; }
/// <summary>
/// Type of Generator.
/// </summary>
public SignalGeneratorType Type { get; set; }
/// <summary>
/// Length Seconds for the Sweep Generator.
/// </summary>
public double SweepLengthSecs { get; set; }
/// <summary>
/// Reads from this provider.
/// </summary>
public int Read(float[] buffer, int offset, int count)
{
int outIndex = offset;
// Generator current value
double multiple;
double sampleValue;
double sampleSaw;
// Complete Buffer
for (int sampleCount = 0; sampleCount < count / waveFormat.Channels; sampleCount++)
{
switch (Type)
{
case SignalGeneratorType.Sin:
// Sinus Generator
multiple = TwoPi * Frequency / waveFormat.SampleRate;
sampleValue = Gain * Math.Sin(nSample * multiple);
nSample++;
break;
case SignalGeneratorType.Square:
// Square Generator
multiple = 2 * Frequency / waveFormat.SampleRate;
sampleSaw = ((nSample * multiple) % 2) - 1;
sampleValue = sampleSaw > 0 ? Gain : -Gain;
nSample++;
break;
case SignalGeneratorType.Triangle:
// Triangle Generator
multiple = 2 * Frequency / waveFormat.SampleRate;
sampleSaw = ((nSample * multiple) % 2);
sampleValue = 2 * sampleSaw;
if (sampleValue > 1)
sampleValue = 2 - sampleValue;
if (sampleValue < -1)
sampleValue = -2 - sampleValue;
sampleValue *= Gain;
nSample++;
break;
case SignalGeneratorType.SawTooth:
// SawTooth Generator
multiple = 2 * Frequency / waveFormat.SampleRate;
sampleSaw = ((nSample * multiple) % 2) - 1;
sampleValue = Gain * sampleSaw;
nSample++;
break;
case SignalGeneratorType.White:
// White Noise Generator
sampleValue = (Gain * NextRandomTwo());
break;
case SignalGeneratorType.Pink:
// Pink Noise Generator
double white = NextRandomTwo();
pinkNoiseBuffer[0] = 0.99886 * pinkNoiseBuffer[0] + white * 0.0555179;
pinkNoiseBuffer[1] = 0.99332 * pinkNoiseBuffer[1] + white * 0.0750759;
pinkNoiseBuffer[2] = 0.96900 * pinkNoiseBuffer[2] + white * 0.1538520;
pinkNoiseBuffer[3] = 0.86650 * pinkNoiseBuffer[3] + white * 0.3104856;
pinkNoiseBuffer[4] = 0.55000 * pinkNoiseBuffer[4] + white * 0.5329522;
pinkNoiseBuffer[5] = -0.7616 * pinkNoiseBuffer[5] - white * 0.0168980;
double pink = pinkNoiseBuffer[0] + pinkNoiseBuffer[1] + pinkNoiseBuffer[2] + pinkNoiseBuffer[3] + pinkNoiseBuffer[4] + pinkNoiseBuffer[5] + pinkNoiseBuffer[6] + white * 0.5362;
pinkNoiseBuffer[6] = white * 0.115926;
sampleValue = (Gain * (pink / 5));
break;
case SignalGeneratorType.Sweep:
// Sweep Generator
double f = Math.Exp(FrequencyLog + (nSample * (FrequencyEndLog - FrequencyLog)) / (SweepLengthSecs * waveFormat.SampleRate));
multiple = TwoPi * f / waveFormat.SampleRate;
phi += multiple;
sampleValue = Gain * (Math.Sin(phi));
nSample++;
if (nSample > SweepLengthSecs * waveFormat.SampleRate)
{
nSample = 0;
phi = 0;
}
break;
default:
sampleValue = 0.0;
break;
}
// Phase Reverse Per Channel
for (int i = 0; i < waveFormat.Channels; i++)
{
if (PhaseReverse[i])
buffer[outIndex++] = (float)-sampleValue;
else
buffer[outIndex++] = (float)sampleValue;
}
}
return count;
}
/// <summary>
/// Private :: Random for WhiteNoise & Pink Noise (Value form -1 to 1)
/// </summary>
/// <returns>Random value from -1 to +1</returns>
private double NextRandomTwo()
{
return 2 * random.NextDouble() - 1;
}
}
/// <summary>
/// Signal Generator type
/// </summary>
public enum SignalGeneratorType
{
/// <summary>
/// Pink noise
/// </summary>
Pink,
/// <summary>
/// White noise
/// </summary>
White,
/// <summary>
/// Sweep
/// </summary>
Sweep,
/// <summary>
/// Sine wave
/// </summary>
Sin,
/// <summary>
/// Square wave
/// </summary>
Square,
/// <summary>
/// Triangle Wave
/// </summary>
Triangle,
/// <summary>
/// Sawtooth wave
/// </summary>
SawTooth,
}
}В чём собственно проблема?
На клавише "Старт" у меня стоит такой код:WaveOut _waveOutGene = new WaveOut(); SignalGenerator wg = new SignalGenerator(); wg.Type = SignalGeneratorType.White; // тут выбираю цвет шума float z1 = 20; // это начальная частота float z2 = 20000; // это конечная частота wg.Frequency = (float)(z1); // Тут назначаем Нижнюю частоту wg.FrequencyEnd = (float)(z2); // Тут назначаем Верхнюю частоту _waveOutGene.Init(wg); _waveOutGene.Play(); // тут уже запуск самого генератора
меняю частоту
, допустимс 20-20 000
Гцдо 15-15 000
разницы я не слышу!
Считается что разницу в таких частотах можно услышать даже без каких-то специальных программ по диагностике звука, но хоть убей - я не слышу разницы между ними. Быть может мой код по изменению частот не верно написан? Если кто знает - подскажите пожалуйста!Заранее большое спасибо!
Решение задачи: «Меняю значение высоких и низких звуковых частот»
textual
Листинг программы
//... case SignalGeneratorType.White: // White Noise Generator sampleValue = (Gain * NextRandomTwo()); break;