-1

I want to play a sound(tone) at specified volumes and frequencies but want the duration of playback fixed say 2 seconds.

My code is similar to one given here.

            double freq, volume;
            WaveTone tone = new WaveTone(freq, volume);
            stream = new BlockAlignReductionStream(tone);
            output = new DirectSoundOut();
            output.Init(stream);
            output.Play();

I tried to use latency in DirectSoundOut() above but it did not work as desired. I have to change freq and volume dynamically for each playback.

I need to know the exact duration of playback of tone.

Kamil Budziewski
  • 22,699
  • 14
  • 85
  • 105
  • Similar or it's your code? Have you searched google, or just asked question? – Kamil Budziewski Jul 27 '13 at 16:58
  • @wudzik Similar to my code and of course Yes I did? Now can you help me or will ask questions in response to question? Any way Thanks, for sparing time. – Muhammad Mansoor Jul 27 '13 at 17:10
  • so why don't you paste your actual code? Sorry for wasting your precious time, but asking good question can save much time. http://stackoverflow.com/questions/5485577/c-sharp-naudio-playing-sine-wave-for-x-milliseconds?rq=1 here you see that you can't pass time to naudio – Kamil Budziewski Jul 27 '13 at 17:19
  • Its not NAudio sir, YOu are using system beep in it. I want to use NAudio – Muhammad Mansoor Jul 27 '13 at 17:49

1 Answers1

0

The WaveTone class (assuming you're using one of the ones I just googled) probably provides an endless stream of data. If you want to limit the output to a specific duration you'll need to either load a specific amount of data into another buffer/stream or modify the WaveTone class to stop producing data past the duration.

Something like this:

class WaveTone : WaveStream
{
    readonly WaveFormat Format;
    public readonly double Frequency;
    public readonly double Amplitude;
    public readonly double Duration;

    readonly long streamLength;

    long pos;

    const double timeIncr = 1 / 44100.0;
    readonly double sinMult;

    public WaveTone(double freq, double amp)
        : this(freq, amp, 0)
    { }

    public WaveTone(double freq, double amp, double dur)
    {
        Format = new WaveFormat(44100, 16, 1);
        Frequency = freq;
        Amplitude = Math.Min(1, Math.Max(0, amp));
        Duration = dur;

        streamLength = Duration == 0 ? long.MaxValue : (long)(44100 * 2 * Duration);

        pos = 0;

        sinMult = Math.PI * 2 * Frequency;
    }

    public override WaveFormat WaveFormat
    {
        get { return Format; }
    }

    public override long Length
    {
        get { return streamLength; }
    }

    public override long Position
    {
        get { return pos; }
        set { pos = value; }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        if (pos >= streamLength)
            return 0;
        int nSamples = count / 2;
        if ((pos + nSamples * 2) > streamLength)
            nSamples = (int)(streamLength - pos) / 2;

        double time = pos / (44100 * 2.0);
        int rc = 0;
        for (int i = 0; i < nSamples; i++, time += timeIncr, ++rc, pos += 2)
        {
            double val = Amplitude * Math.Sin(sinMult * time);
            short sval = (short)(Math.Round(val * (short.MaxValue - 1)));
            buffer[offset + i * 2] = (byte)(sval & 0xFF);
            buffer[offset + i * 2 + 1] = (byte)((sval >> 8) & 0xFF);
        }

        return rc * 2;
    }
}
Corey
  • 15,524
  • 2
  • 35
  • 68