Controlling the speed of ast_control_streamfile

I am using ControlPlayback to play specific sound files. We want to be able to select the speed at which the file is played. Can anyone point me in the general direction of where in Asterisk the actual file is played (I am not a C dev and it’s hard for me to follow). I want to see how hard it would be at the SRC level to get Asterisk to play the file at a faster speed and possibly then add it as a feature to Asterisk

The waitstream_core function is generally what is doing the playback loop[1] while the ast_readaudio_callback function[2] is what is reading the frame from the format module and writing it out to the channel. There is no functionality to speed it up, and you can’t just read the frames faster because that would still give you the same number of frames. You would have to do audio manipulation most likely, and then transcode it probably.

[1] asterisk/file.c at 20 · asterisk/asterisk · GitHub
[2] asterisk/file.c at 20 · asterisk/asterisk · GitHub

I think that speeding up would typically be done in the frequency domain, so you would probably need to do FFTs and IFFTs. This assumes that you want to maintain the correct formant structure (and basic voice pitch). There are probably other subtleties, e.g. to maintain phase continuity. It may be easier to do on a vocoded stream (e.g. GSM), as these do you frequency domain coding.

The only simpler approach would be to completely drop every nth frame. Each frame would still be long enough to represent the frequency structure, but short enough to not to miss significant detail. You’ll obviously get artefacts because of this, which will need some sort of filtering.

For these approaches, I think you would need a strong digital signal processing background, in which case I would expect you to be familiar with C.

You could work in large chunks, but that would not be intelligible, although it might be enough to find the right place in a file.

ldo@theon:~> ffmpeg -help filter=atempo
...
Filter atempo
  Adjust audio tempo.
    Inputs:
       #0: default (audio)
    Outputs:
       #0: default (audio)
atempo AVOptions:
  tempo             <double>     ..F.A....T. set tempo scale factor (from 0.5 to 100) (default 1)

Just tried it with ffplay on a music .wav file I happened to have handy, and it seemed to work quite nicely in real time.

Yes. But it will be doing a lot of digital signal processing to achieve that.

If the OP wants to go that way, they should be developing a general external audio filter capability, but while requiring less maths, that is not going to be an easy change.

The starting point for doing this just in Asterisk would probably be the PITCH_SHIFT function. You are basically going to have to combine sub- or over-sampling, to change the rate, with a pitch shift operation, to correct the resulting frequency domain distortion.

It also has all the bits needed to interpose itself in a media stream, although probably not between a file and a channel - you might need to insert a local channel.

Note that PITCH_SHIFT does use FFTs.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.