Skip to content

NextGenOutput

Erik Massop edited this page Nov 4, 2017 · 1 revision

XMMS2 NextGen Output

Design Idea Notes and Brain Thoughts for Nextgen Output II Turbo Edition

Separate output.c into output.c and playback.c

output.c would take care of volume set/get and output plugin related matters
playback.c would handle playback state matters

Unify Output plugin operation to the pull style by using a pulling thread
to drive push based output plugins.

Remove locks in by having play/pause/stop/seek/tickle commands
'send a message' to the playback (output filler) thread, rather than
using conds and critical sections

Make playback speed and direction part of the overall playback state,
even if these get handled by xforms down the chain, if the speed and direction
state is not a part of the overall playback state, really awkward measures
need to be taken to propagate information such as the actual position in time
of the chain. These are the only 'effects' that modify the way playtime and position
would be calculated.

Other things:
Unify speed, direction and resampling xform, this is the way to get optimal buffering
and cpu usage.

raw file xform should use 64k buffers on x86-64 linux systems, if not all linux systems. 
This is the optimal size / context switch tradeoff for read/write calls on linux.


Transitions Plugins
Once the above exists, we can move on to transitions plugins ;)

David Richards aka oneman

Goals:

    Highest Quality, Performance, Reliability and Flexibility along with code readability and simplicity
    *   As few Mutex's as possible (looking good now)
    *   Low to zero possibility of underun
    *   Lowest CPU Usage (doing well here, but more flexibility for jack users desired)
    *   Fewest Copies of Bytes (doing fine here already)
    *   Most sensible defaults, most users will not need to touch output settings
    *   Optional, be it by compile time or runtime, crosslapping durring seeking or track jumping 
                              (Manual track change, not natural track progression)
    *   Optional Fade Down on pause, Fade In on Resume DONE RIGHT, optional length
    *       Optional skipping of calculating latency in playtime (Only important for jack users, where its known and
                                      ultimately irrelivant, and a long code path that could cause xrun)

    * Merge to -devel ASAP

Next Level ( NextGen+ ) Potential Goals: 

    *       Backwards playback (Possibly better done as an xform Not known yet)
    *   Internal Mixer, X number of tracks going at once, volume control/crossfading, control effect parameters per chain
    *   Multiple Outputs 


Testing:

If you want to test this code, find me, oneman, in the xmms2 irc channel.


Contribute to my efforts with cryptocash:

I'm poor! I accept bitcoins at this address: 12c2o17PBug1zh5XxaGi3FB5BXETbcRobp


The output buffer:

    Currently when a user seeks or jumps tracks in the middle of playback, the output buffer is dumped. This can cause two glitches
    depending on several factors most importantly the sound at the moment. 1) A glitch pop or crack sound 2) A Gap in output
    In the prebeta of nextgen output I have a "stacked buffer" model, meaning, the buffer is not dumped on a seek or jump, the samples
    post seek or jump are just 'stacked' on the end of the existing output buffer as it rolls along 

    
Seek/jump in Dr. No:     ("Dump Buffer")

Time:   ----------s----------
Output: ---------- ----------       << Glitch / Gap in output due to buffer dump

Seek/jump in nextgen-output prebeta:    ("Stacked Buffer")

Time:   ----------s----------
Output: ---------------------    << Output is gapless, but the seek or jump is delayed by the size of the output buffer
                   ^Seek heard here

There maybe a glitch in the sound, but it is generally less noticable due to no gap
The delay depends on the size of the output buffer and the sample size and rate
The common case is the size of 32768 bytes and Stereo S16 Samples @ 44100khz
This comes out to 2 bytes per samples times 2 for stereo or 32768 / 4 = 8192 samples
8192 / 44.1 (samples per millisecond) = 185ms delay in hearing the seek 
So the delay is about 1/5th of a second

There is no pleasing some people, many, none of which have tested this, claim that its a long time, and will make things feel laggy, etc.
In reality it ends up making the sound output more smooth and does not feel laggy. However I aim to please, and get this code into -devel
as soon as possible, so I think it should be possible for several buffer options be availible be it compile time or runtime options.
So lets call the buffer strategy in Dr. No the "dump buffer strategy", and the one currently in nextgen-output the "stacked buffer strategy"
Here is some other strategies. 

Crosslap Seek / Jump    ("Crosslap Stacked Buffer")

Time:   ----------s----------
Output: -----------=---------
               ^Some Samples from old audio and new are lapped
 
See this page for information on crosslapping: http://xiph.org/vorbis/doc/vorbisfile/crosslap.html



Crossfade Seek Jump ("Crossfade Crosslap Stacked Double Buffer")

    This is the same as above, but samples are also crossfaded, meaning volume for old is going down and new is going up
    The length of the crossfade would be configurable. This involves also a second ringbuffer, but it doesn't nessasarily
    mean a third ("mixed samples") ringbuffer. There could be a third mixed ringbuffer, or the two buffers could be mixed
    at the time that the output is read. Only testing will determine which is more effiecient if it matters. The cpu cycles
    needed to mix would be consistant everytime. The fade would start as soon as possible, this means that the lowest possible
    latency when seeking / jumping without a gap would happen, unlike the solo stacked buffer, we don't have to wait for it to
    be played out, merely for the next samples to be ready, before we start outputing the mix

Time:   ----------s----------
Output: -----------==--------
           ^Samples are crossfaded and crosslapped


Continous switch Seek/jump ("Switched Double Buffer")

This is a compromise between the dumped buffer and stacked buffer, the buffer is not dumped, the output continues to output the old
samples until the new ones are availible, as soon as they are the next read will be from the other buffer. Thus Output will be continous,
and latency minimal. This should please the haters (if they can be pleased) of any additional delay, as the decoding/reading of the old audio can stop,
and the new audio be read without so any old samples played are just taking the place of what would be a gap in the sound ie. buffer underrun.

Crosslapped switch Seek/Jump ("Crosslapped Switched Double Buffer")
The same as above but crosslapped.

P1060401.JPG

xmms2_cde_example.jpg

Clone this wiki locally