Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Play wav audio until position #175

Closed
Herz3h opened this issue Mar 20, 2017 · 14 comments
Closed

Play wav audio until position #175

Herz3h opened this issue Mar 20, 2017 · 14 comments

Comments

@Herz3h
Copy link

Herz3h commented Mar 20, 2017

Hello,

I followed tutorial on this page and managed to successfully play a wav file. However i'd like to play the audio until a position in time is reached (say for ex until 3rd sec then pause or stop), how do i go about this ?

The only idea i have is to use a thread which checks position of the audio and pause it when it reaches the position i want but not sure if thats how it should be done.

Thanks in advance

@markheath
Copy link
Contributor

You can use a timer that checks if you've reached a certain point which is ok in some circumstances but not accurate.

A better approach would be to use OffsetSampleProvider and the Take method to limit the total amount to be read before it reaches the end.

@Herz3h
Copy link
Author

Herz3h commented Mar 28, 2017

Edit i found an example here : http://markheath.net/post/naudio-play-extract

However i have a problem, when i use that example, then later i try to read another chunk of the audio file by doing this :

trimmed.SkipOver = TimeSpan.FromSeconds(25);
trimmed.Take = TimeSpan.FromSeconds(5);
player.Play();

It doesn't do anything, no sound played.

TL;DR plays only one chunk of the file then when i try to read other chunk, doesn't work

@Herz3h
Copy link
Author

Herz3h commented Mar 29, 2017

Any help please, i'm stuck

@markheath
Copy link
Contributor

For this use, I'd make a WaveStream implementation whose Read method delegated down to the Read method of your WaveFileReader, but stopped once the desired position was read. This would allow you to reposition the underlying WaveFileReader to the start and read again.

@Herz3h
Copy link
Author

Herz3h commented Apr 4, 2017

Do you mean i copy WaveFileReader file and rename it ? I've checked the Read method of the WaveFileReader but i don't quite see how i'd tell it to stop at position i want.

Could you provide an example ?

@markheath
Copy link
Contributor

No, you create a custom class that inherits from WaveStream. In the constructor take a WaveStream as input which will be your WaveFileReader. In the Read method, read from the input, but only as far as your maximum position. There's actually already a class in NAudio that's probably good enough called WaveOffsetStream - try using that with StartTime of TimeSpan.Zero, source offset of TimeSpan.Zero and source length of the duration you want to play for

@Herz3h
Copy link
Author

Herz3h commented May 4, 2017

I'm sorry but i'm not sure how do i play the sound then after creating a WaveOffsetStream instance with the startTime and length i want. Atm i'm using this code to play a sound :

WaveOutEvent waveOutEvent = new WaveOutEvent();
AudioFileReader  wavFileReader = new AudioFileReader(audioPath);
OffsetSampleProvider trimmed = new OffsetSampleProvider(wavFileReader);
waveOutEvent.Init(trimmed);

then

waveOutEvent.Play()

where does the WaveOffsetStream object go in this code ?

Edit :

I found a way like this :

WaveOutEvent waveOutEvent = new WaveOutEvent();
WaveOffsetStream waveOffsetStream = new WaveOffsetStream(fileReader, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(3.0));
waveOutEvent.Init(waveOffsetStream);
waveOutEvent.Play();

but now my question is if i want to read another part of the audio, do i have to init the waveOutEvent with a new WaveOffsetStream ? If so how do i do that because i get an error when i try to Init the waveOutEvent again after the first time.

@markheath
Copy link
Contributor

markheath commented May 9, 2017 via email

@Herz3h
Copy link
Author

Herz3h commented May 9, 2017

Ok i managed to read part of the audio. But i have this issue where i have to delete old waveOutEvent and create a new one to play another part of the audio. I feel like i'm doing it wrong here.

Am i supposed to delete WaveOutEvent object and create new one each time i want to play an audio part?

@markheath
Copy link
Contributor

yes, if you're going to play audio at a completely different sample rate / bit depth, but you don't have to otherwise. you can use a MixingSampleProvider with ReadFully set to true so it never stops, and then insert new bits of audio as mixer inputs when you want to play them. (see my article here: http://www.markheath.net/post/fire-and-forget-audio-playback-with)

@Herz3h
Copy link
Author

Herz3h commented May 23, 2017

Ok i just keep WaveOffsetStream as it does what i need. Thanks for the help !!

Just have one issue. I run a thread that fetches the audio position and sends it to callback but the currentTime/Position doesn't update as fast as i want. For instance i have this :

Position CurrentTime
1108800 00:00:11.5600000
1108800 00:00:11.5600000
1108800 00:00:11.5600000
1123200 00:00:11.7100000
1123200 00:00:11.7100000

It skips position 00:00:11.57 to 00:00:11:70, any way i can set how fast is the position updated?

Or is this due to the lock here : https://github.com/naudio/NAudio/blob/master/NAudio/Wave/WaveStreams/WaveOffsetStream.cs#L145

@markheath
Copy link
Contributor

it's based on the latency and size of buffers the audio card is using. You'd need to plug into the IWavePosition interface to find out how far through the current buffer we are

@Herz3h
Copy link
Author

Herz3h commented Jun 27, 2017

Do you mean i'd have to make my own WaveOutEvent which inherits IWavePosition and implement GetPosition in a different way ?

Because atm, trying to do waveOutEvent.GetPosition() also has big gaps like my previous post (doesn't update as often)

@markheath
Copy link
Contributor

WaveOutEvent already implements IWavePosition, so you can use that to find out how exactly much audio has been played so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants