Rolf of Saxony
Rolf of Saxony

Reputation: 22438

GStreamer issue with time

I use GStreamer to play audio and regularly require a timestamp of where I am in the file.

If I adjust the rate of play, be it using a seek command specifying a new play rate or if I use a plugin like “pitch” to adjust the “tempo” component. All timings go out of the window as GStreamer adjusts the length of the audio and its current position to factor in the speed that it is playing at. So what was at say 18 seconds is now at 14 seconds, for example.
I have also tried stopping the audio and starting afresh passing the new settings and also issuing the seek with a rate of 1.00 and also the tempo rate neither has worked. I have run out of ideas for the moment, thus this plea to SO.

Example code

#Slow down rate of file play
def OnSlow(self, evt):
    media_state = self.media_get_state()
    self.rate = Gpitch.get_property("tempo")
    if self.rate > 0.2:
        self.rate = self.rate - 0.10
        Gpitch.set_property("tempo", self.rate)
        r = "%.2f" % (self.rate)
        self.ma3.SetLabel("Speed: "+r)
        if media_state == Gst.State.PLAYING or media_state == Gst.State.PAUSED:
            self.timer.Stop() #momentarily stop updating the screen
            seek_event = Gst.Event.new_seek(self.rate, Gst.Format.TIME, 
                (Gst.SeekFlags.FLUSH),#NONE),
                Gst.SeekType.NONE, 0, Gst.SeekType.NONE, -1)
            Gplayer.send_event(seek_event)
            time.sleep(0.1)
            self.timer.Start() #Restart updating the screen

I have tried multiplying the duration and the current position by the adjustment in an attempt to pull or push the timestamps back to their positions, as if it were being played at normal speed but to no avail.

I have been pulling my hair out over this and the real kick in the teeth, is that, if I perform the same task using Vlc as my audio engine it works but I have to alter the pitch separately. The whole reason for moving over to GStreamer was that the pitch plugin tracks the “tempo” component and yet if I cannot get accurate and consistent timestamps, the project is dead in the water.

My question, has anybody a) come across this issue and b) mastered it

Upvotes: 0

Views: 838

Answers (1)

Rolf of Saxony
Rolf of Saxony

Reputation: 22438

The answer, for anyone who finds themselves in a similar predicament, seems to lie with a fundamental tussle between the soundtouch pitch plugin and GStreamer's rate of play.

Audacity even makes a note of it in their User Manual.

The only way I eventually found a way round the problem, was to ditch the pitch plugin entirely from the pipeline, as just having it in there was enough to mess things up.
Instead, I used the ladspa-am-pitchshift-1433-so-ampitchshift plugin to adjust the pitch of the audio and left GStreamer to vary the rate using normal seek commands whilst altering the rate, to give slower and faster rates of play.
In this way the timestamps remain consistent but the pitch has to be manually adjusted. Although it can be semi-automated by picking from a list of predefined pitch values for given rates of play.
I trust that this saves someone else 2 days of head scratching.

Additional Note:
Even though GStreamer works in nanoseconds and one could be forgiven for thinking that not using the flag Gst.SeekFlags.ACCURATE, when performing a seek, wouldn't make that much difference, one would be very much mistaken.
I have noticed that not using the ACCURATE flag can make a difference of up to 10 seconds when GStreamer is asked to report its current position, if the seek didn't use the ACCURATE flag.
So forewarned is forearmed. (note that using this flag will make the seek take longer but at least if gives consistent results)

Upvotes: 0

Related Questions