tag:blogger.com,1999:blog-6822536077160579260.post122743655341464082..comments2023-06-05T14:25:52.227+01:00Comments on Sound Code: Playback of Sine Wave in NAudioAnonymoushttp://www.blogger.com/profile/17900587357903273800noreply@blogger.comBlogger59125tag:blogger.com,1999:blog-6822536077160579260.post-78940359765583305592014-01-02T22:09:45.639+00:002014-01-02T22:09:45.639+00:00With WasapiOut at least I think you can get it jus...With WasapiOut at least I think you can get it just by asking for the WaveFormat before you call Init. (It's been a while, but I think that's how it works from memory). By the way, best to ask NAudio questions over at the CodePlex discussion site if possible (naudio.codeplex.com)Anonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-1029643094509835712014-01-02T21:50:02.785+00:002014-01-02T21:50:02.785+00:00Actually, by stepping through the NAudio initializ...Actually, by stepping through the NAudio initialization, I learned that my sound card's sample rate indeed is different from the one I got from the default constructor. When setting the sample rate correctly there's no lag (an no glitches, which also occurred before). <br /><br />Is there a way to get the sound card's sample rate from NAudio? <br />Unknownhttps://www.blogger.com/profile/03160927907722433196noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-80268242823317554602014-01-02T00:32:05.717+00:002014-01-02T00:32:05.717+00:00I haven't given much thought to where the samp...I haven't given much thought to where the sampling rate comes from, so I might be resampling without intending to. You've seen my initialization code (in my first post), and the code producing the sine wave is pretty much as your example. If I understand your code correctly, that would imply that the sampling frequency is set by the default constructor of WaveProvider32, i.e. 44100 Hz in mono?<br /><br />And I see that it is possible to use other constructors to set other sample rates, but how would I know what sample rate the soundcard has? <br />Unknownhttps://www.blogger.com/profile/03160927907722433196noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-54250772554111183152014-01-01T22:31:21.286+00:002014-01-01T22:31:21.286+00:00why is an MFT involved? Are you resampling? If pos...why is an MFT involved? Are you resampling? If possible work at the sample rate of the soundcard. But I probably should do something a bit cleverer with that MFT read size code.Anonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-19354148494905914232014-01-01T22:26:00.664+00:002014-01-01T22:26:00.664+00:00Hi!
Thanks for your swift reply!
I stepped throu...Hi!<br /><br />Thanks for your swift reply!<br /><br />I stepped through the NAudio code. The reported latency from the AudioClient is 11 ms. <br /><br />However, when stepping through the code I noticed that in MediaFoundationTransform you explicitly read one second from the provider: <br /><br /> private IMFSample ReadFromSource()<br /> {<br /> // we always read a full second<br /> int bytesRead = sourceProvider.Read(sourceBuffer, 0, sourceBuffer.Length);<br /><br />Maybe there's something I don't understand well enough, but by reading once a second, doesn't that imply that changes I make in the audio generation can be delayed up to one second until they are heard? <br /><br />Thanks a lot for your help, and I wish you a happy New Year! :-)Unknownhttps://www.blogger.com/profile/03160927907722433196noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-47927939736004316852013-12-31T19:42:12.511+00:002013-12-31T19:42:12.511+00:00Hi!
Thanks for your swift reply!
I stepped throu...Hi!<br /><br />Thanks for your swift reply!<br /><br />I stepped through the NAudio code. The reported latency from the AudioClient is 11 ms. <br /><br />However, when stepping through the code I noticed that in MediaFoundationTransform you explicitly read one second from the provider: <br /><br /> private IMFSample ReadFromSource()<br /> {<br /> // we always read a full second<br /> int bytesRead = sourceProvider.Read(sourceBuffer, 0, sourceBuffer.Length);<br /><br />Maybe there's something I don't understand well enough, but by reading once a second, doesn't that imply that changes I make in the audio generation can be delayed up to one second until they are heard? <br /><br />Thanks a lot for your help, and a happy New Year as well! :-)<br />Unknownhttps://www.blogger.com/profile/03160927907722433196noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-30496081671766128322013-12-31T14:16:45.927+00:002013-12-31T14:16:45.927+00:00I think in shared mode, sometimes your requested l...I think in shared mode, sometimes your requested latency can be ignored. If you can debug the NAudio code, look in the Init method of WasapiOutRTAnonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-38093266581144890472013-12-31T12:43:26.663+00:002013-12-31T12:43:26.663+00:00Hi!
Thanks a lot for your work on NAudio, it'...Hi!<br /><br />Thanks a lot for your work on NAudio, it's much appreciated!<br /><br />The last few days I have been working with additive synthesis based on this example. At first I used WaveOut (as in your code), but then I started moving my code to a Windows Store App. I know that NAudio isn't officially available for such apps, but I found some post stating how to use NuGet to get a pre-release. I changed WaveOut to WasapiOutRT like this: <br /><br /> _sampleMixer = new MixingSampleProvider(_voices[0].SampleProviders);<br /> _sampleToWaveProvider = new SampleToWaveProvider(_sampleMixer);<br /> _waveOut = new WasapiOutRT(AudioClientShareMode.Shared, 100);<br /> await _waveOut.Init(_sampleToWaveProvider);<br /> _waveOut.Play();<br /><br />It works, but there's a horrible latency. I'm not sure, but I don't think it lagged as much when using WaveOut. I am a total beginner in programming audio like this, but when I stepped through the code I realized that the Read() method is called just once every second when using WasapiOutRT, with a buffer size of 44100, as opposed to every ~150ms or so on WaveOut (buffer size 6615), and to me that sounds like a source of latency. Or do I miss something? <br /><br />Best regards, <br />HÃ¥kan ErikssonUnknownhttps://www.blogger.com/profile/03160927907722433196noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-22441796660714059712013-07-25T18:44:47.339+01:002013-07-25T18:44:47.339+01:00Tahnk you for this great Post. I have noticed that...Tahnk you for this great Post. I have noticed that it is working wrong in stereo-mode. To fix it i have added a line to proof if floatarray is even number:<br /><br /> for (int n = 0; n < sampleCount; n++)<br /> {<br /> buffer[n + offset] = (float)(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));<br /> if (this.WaveFormat.Channels == 1 || (n + offset) % 2 == 0)<br /> sample++;<br /> if (sample >= sampleRate) sample = 0;<br /> }<br /><br />I'm sorry for my bad English and hope my Coment ist helpfully.Rudihttps://www.blogger.com/profile/01434571279457456307noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-52257243813501854242013-07-25T18:41:53.487+01:002013-07-25T18:41:53.487+01:00Thanks for the Post. I have noticed that it work w...Thanks for the Post. I have noticed that it work wrong with Stereo....<br />To fix it i add a line in the SineWaveProviderClass to proof if byte is even Number.<br /><br /> for (int n = 0; n < sampleCount; n++)<br /> {<br /> buffer[n + offset] = (float)(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));<br /> if (this.WaveFormat.Channels == 1 || (n + offset) % 2 == 0)<br /> sample++;<br /> if (sample >= sampleRate) sample = 0;<br /> }<br /><br />I'm sorry for my bad english and hope it ist helpflull.<br /><br />Rudihttps://www.blogger.com/profile/01434571279457456307noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-71088443587499390612013-03-12T14:54:27.852+00:002013-03-12T14:54:27.852+00:00hi Alain, this article is about how to generate si...hi Alain, this article is about how to generate sine waves, rather than how to detect frequency. To do that, I'd recommend researching FFT or autocorrelation algorithms.Anonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-15240757811778781092013-03-12T14:25:56.564+00:002013-03-12T14:25:56.564+00:00Hey Mark,
I'm a student and have the assignme...Hey Mark,<br /><br />I'm a student and have the assignment to create a recording application which then records microphone input and has to determine the frequency and then display which note it is related to said frequency.<br /><br />Will this article be the good way to follow in order to achieve this (retrieval of frequency)?<br /><br />Thanks!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-1746246246383411542012-09-05T17:27:13.716+01:002012-09-05T17:27:13.716+01:00offset is just the offset into the buffer that you...offset is just the offset into the buffer that you should write to so this will normally be zero. You maintain state outside the Read method to know where you were up to.Anonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-77396703550138620452012-08-22T10:02:44.018+01:002012-08-22T10:02:44.018+01:00If I want to Stop the Play automatically, after fi...If I want to Stop the Play automatically, after finishing the buffer, what can I do?<br /><br />It seems that the read method will be executed by offset=0 each time!Anonymoushttps://www.blogger.com/profile/04791836548630284580noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-81046725521258781572012-07-10T09:46:05.908+01:002012-07-10T09:46:05.908+01:00creating other waveforms is easy, especially sawto...creating other waveforms is easy, especially sawtooth/triangle/square, as they can be easily calcualted. You can also use a wavetable.<br /><br />To eliminate clicks, either fade out and back in over a short period (a few ms), or implement portamento. I hope to blog about that at smoe point.Anonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-71028694355167179542012-07-09T23:39:48.770+01:002012-07-09T23:39:48.770+01:00Hello,
How could I use this to create other wavef...Hello,<br /><br />How could I use this to create other waveform types such as a triangle or sawtooth?<br /><br />Also is there any way to avoid a click when changing frequencies during playback?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-18473571688224245852012-03-05T18:59:06.336+00:002012-03-05T18:59:06.336+00:00@John, For position, just return the number of byt...@John, For position, just return the number of bytes read. For a sine generator there is no point allowing position to be set, so either throw an exception or just ignore the position value.Anonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-58886494182553030512012-03-05T17:39:43.529+00:002012-03-05T17:39:43.529+00:00Hi there Mark,
I've converted this into a der...Hi there Mark,<br /><br />I've converted this into a derived WaveStream to allow mixing using WaveMixerStream.<br /><br />I've added:<br /><br />public override long Length<br />{<br /> get { return long.MaxValue; }<br />}<br /><br />However, I'm not sure how to get/set position.<br /><br />Could you help me out?<br /><br />Thanks.John Dixonhttps://www.blogger.com/profile/03662155230454542039noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-8678424212024314912012-01-05T13:45:53.491+00:002012-01-05T13:45:53.491+00:00thanks a lot Mark
great workthanks a lot Mark<br />great workMuratnoreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-59951612169898020862011-10-18T16:02:02.244+01:002011-10-18T16:02:02.244+01:00@Steve,
inherit from WaveProvider32 and provide yo...@Steve,<br />inherit from WaveProvider32 and provide your own float samples in the Read methodAnonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-49198456556491614462011-10-17T10:28:26.962+01:002011-10-17T10:28:26.962+01:00@Kyle, you can use the WaveFileWriter class from N...@Kyle, you can use the WaveFileWriter class from NAudio to do thisAnonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-17862463646142823092011-10-15T17:24:27.784+01:002011-10-15T17:24:27.784+01:00HI Mark
I was wondering maybe if there was a way ...HI Mark<br /><br />I was wondering maybe if there was a way to save the data directly to a .wav file ?Kylenoreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-63438169481641988862011-10-14T22:57:20.476+01:002011-10-14T22:57:20.476+01:00Hey Mark-
I have been playing with the NAudio lib...Hey Mark-<br /><br />I have been playing with the NAudio library for a couple days. I got the sine wave to play. Very cool. But now I want to play back my own arbitrary float data. What's the best way to stuff in float data to a WaveOut object? My guess is to use BufferedWaveProvider. I'm a little uncertain how to get that class to handle float data though.<br /><br />I tried instantiating BufferedWaveProvider a couple of ways. My first shot was using WaveForm(fs,1). I also tried WaveFormat.CreateIeeeFloatWaveFormat(fs,1).<br /><br />But then I was shaky on how to pack my float data into a byte array to be used by the AddSamples() method of BufferedWaveProvider.<br /><br />What do you recommend?Stevehttps://www.blogger.com/profile/14088652155699026580noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-65855917584399952562011-08-09T15:47:57.509+01:002011-08-09T15:47:57.509+01:00@Matt, I can't see any reason why this wouldn&...@Matt, I can't see any reason why this wouldn't work with the latest NAudio codeAnonymoushttps://www.blogger.com/profile/17900587357903273800noreply@blogger.comtag:blogger.com,1999:blog-6822536077160579260.post-48539041749660842222011-08-05T15:21:09.206+01:002011-08-05T15:21:09.206+01:00Hi Mark,
I was wondering, will the above code sti...Hi Mark,<br /><br />I was wondering, will the above code still work with the latest beta version of NAudio that is on codeplex, or have you included some of the functionality that you suggested you would in the update?Mattnoreply@blogger.com