static void Test_WaveWriter() { var format = new WaveFormat { bytesPerSample = 2, sampleRate = 44100, channels = 1, }; byte[] buffer = new byte[format.bytesPerSample * format.sampleRate]; // for 1 sec string file = "test1.wav"; using (var w = new WaveWriter(format, file)) { #if false WaveFormat.Clear(buffer); w.Write(buffer); #else var provider = new PartialProvider(); provider.Initialize(format); //provider.AddFrequency(440.0, 1500, 0.5f); // without envelope provider.AddPartial(440, 100, 2000, 0.5f, -4f); provider.FlushPartials(); while (!provider.IsEmpty()) { provider.Fill(buffer); w.Write(buffer); } #endif } }
// implement SampleProvider // PlayingThread. public override bool Fill(byte[] buffer) { if (IsEmpty()) // No partials to play { WaveFormat.Clear(buffer); return(true); } int bufferPos = 0; // in bytes int bufferSampleCount = buffer.Length / _format.bytesPerSample; for (int i = 0; i < bufferSampleCount / _format.channels; ++i) { // Add new partials: _addPartials -> _partials if ((_currentSample & 0xFFF) == 0) // don't lock every sample { if (_addPartialsCount > 0) // atomic { lock (_addPartialsLock) { for (int j = 0; j < _addPartialsCount; ++j) { _addPartials[j].SetTime(_currentSample); //Debug.WriteLine("Partial added: {0}", _addPartials[j]); } Array.Copy(_addPartials, 0, _partials, _partialCount, _addPartialsCount); _partialCount += _addPartialsCount; _addPartialsCount = 0; } //Debug.WriteLine("Partials count: {0}", _partialCount); } } int sampleValue = 0; if (_partialCount > 0) { int c = 0; // current partial index for (int j = 0; j < _partialCount; ++j) { // Removing ended partials if (_partials[j].end == _currentSample) { //Debug.WriteLine("Partial removed: {0}", _partials[j]); } else { if (c != j) { _partials[c] = _partials[j]; } // Get sample value sampleValue += _partials[c].partial.GetNextValue(); c += 1; } } if (_partialCount != c) { _partialCount = c; //Debug.WriteLine("Partials count: {0}", _partialCount); } } unchecked { _currentSample += 1; // overflowing } // Write sample value to all channels for (int c = 0; c < _format.channels; ++c) { _format.WriteInt(buffer, bufferPos, sampleValue); bufferPos += _format.bytesPerSample; } } //Debug.WriteLine(FormatBuffer(buffer)); return(true); }