summaryrefslogtreecommitdiffstats
path: root/audio/filter
Commit message (Collapse)AuthorAgeFilesLines
* af_scaletempo2: prioritize louder channels for similarity measureferreum2024-04-121-4/+4
| | | | | | | | | | | | | | | | Playback with many audio channels could be distorted when using scaletempo2. This was most noticeable when there were a lot of quiet channels and few louder channels. Fix this by increasing the weight of louder channels in relation to quieter channels. Each channel's target block energy is factored into the usual similarity measure. This should have little effect on very correlated channels (such as most stereo media), where the factors are very similar for all channels. See-Also: #8705 See-Also: #13737
* various: make filter internal function names more descriptivenanahi2024-04-106-43/+43
| | | | | | | | | Lots of filters have generic internal function names like "process". On a stack trace, all of the different filters use this name, which causes confusion of the actual filter being processed. This renames these internal function names to carry the filter names. This matches what had already been done for some filters.
* af_scaletempo2: fix false reporting of frame availabilitynanahi2024-03-281-1/+2
| | | | | | | | | | | | | | | With certain speed settings, the following can happen at the start of the playback: - can_perform_wsola returns false, so no frames are written - mp_scaletempo2_frames_available returns true when p->input_buffer_final_frames is 0 and target_block_index < 0 This results in infinite loop and completely stalls audio filter processing and playback. Fix this by only checking this condition after the final frame is set. Fixes: 8080d00d7f31a0e1ba25418e0f08474f1a2f1f61
* af_lavcac3enc: fix memory leak on 2ch audiomistraid1212024-03-191-3/+3
| | | | If processing is not required, the frame would be leaked as it is not used.
* various: fix -Wold-style-declaration warningnanahi2024-03-191-1/+1
| | | | warning: `static' is not at beginning of declaration
* af_lavcac3enc: don't use deprecated `avcodec_close`llyyr2024-02-191-1/+9
| | | | | | | | Deprecated upstream https://github.com/FFmpeg/FFmpeg/commit/1cc24d749569a42510399a29b034f7a77bdec34e We need to reallocate the context here because `avcodec_free_context` also frees the context, and we want to reuse the context with some reconfig.
* various: remove trailing whitespaceGuido Cella2023-10-301-1/+1
|
* af_scaletempo2: better defaultsChristoph Heinrich2023-10-151-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Why a bigger search-interval is required: scaletempo2 doesn't do a good job when the signal contains frequencies less then 1/search_interval. With a search interval of 30ms that means anything below 33.333Hz sounds bad. Depending on the genre it's very for music to contain frequencies down to 30Hz, and sometimes even a little bit below that. Therefore a higher default value is needed to handle such cases. Based on that an argument can be made for a value of 50, as that should work down to 20Hz, or something even higher because movies sometimes have some infrasonic content. However the downside of big search intervals is increased CPU usage and intelligibility at higher speeds, as it effectively leads to parts of the audio being skipped. A value of 40 can handle frequencies down to 25Hz, enough for all music except very rare edge cases, while still providing decent intelligibility. Why a smaller window-size is required: Large values reduce intelligibility at high speeds and therefore small values are preferred. However when values get too small it starts to sound weird (similar to librubberband). In my testing a value of 10 already works well, but adding a small safety margin seems like a good idea, especially since it made no noticeable difference to intelligibility, which is why 12 was chosen.
* af_scaletempo: overlap is a factor not a percentageChristoph Heinrich2023-10-071-4/+4
|
* af_scaletempo2: raise max playback rate to 8.0llyyr2023-09-271-1/+1
| | | | | | 4.0 was too low and copied from Chromium defaults when the filter was initially written, there's no good reason for it to be so low, so double it.
* af_scaletempo2: fix missing variable init, remove redundant initferreum2023-09-201-1/+1
|
* af_scaletempo2: truncate final packet to expected lengthferreum2023-09-201-0/+14
| | | | | | | | | | Avoid generating too much audio after EOF. Note: This often has no effect, because less audio is produced than required. Usually this comes to effect with the userspeed filter at high speed (4x) and going back to 1x speed to remove the filter.
* af_scaletempo2: fix processing of final packetferreum2023-09-203-16/+64
| | | | | | | | | | | | After the final input packet, the filter padded with silence to allow one more iteration. That was not enough to process the final frames. Continue padding the end of `input_buffer` with silence until the final frames have been processed. Implementation: Instead of padding when adding final samples, pad before running WSOLA iteration. Count number of added silent frames and remaining input frames for time keeping.
* af_scaletempo2: calculate latency by center of search blockferreum2023-09-202-6/+6
| | | | | | | | | | | | | | | | | | | | | This changes the emitted pts values from the start of the search block to the center of the search block. Change initial `output_time` accordingly. Initial `search_block_index` is irrelevant, because it's overwritten before the first iteration. Using the `output_time` removes the rounding of `search_block_index`, which also fixes the <20 microsecond gaps in timestamps between output packets. Rationale: The variance in audio position was in the range `0..search-interval`. With this change, the range is (- search-interval / 2)..(search-interval / 2)` which ensures lower maximum offset.
* af_scaletempo2: restore exact audio sync on return to 1x speedferreum2023-09-201-1/+9
| | | | | | | | | Target block can be anywhere in the previous search-block, varying by `search-interval` while the filter is active. This resulted in constant audio offset when returning to 1x playback speed. - Move the search block to the target block to sync up exactly. - Drop old frames to minimize input_buffer usage.
* af_scaletempo2: fix speed change latency and pts spikesferreum2023-09-203-42/+51
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The internal time update function involved multiple problems: - Time was updated after WSOLA iteration. The means speed was updated one iteration later than it could be. - The update functions caused spikes of too many or too few samples advanced, leading to audio glitches on speed changes. - The inconsistent updates made it very difficult to produce gapless audio packets. - The `output_time` update function involved complicated feedback: `search_block_index` influenced how many frames from `input_buffer` are retained, which influenced how much `output_time` is changed, which influenced `search_block_index`. With these changes: - Time is updated before WSOLA iterations. Speed changes are effective instantly. - There are no spikes in playback speed during speed changes. - No significant gaps are introduced in output packets. - The time update function becomes (function calls omitted for brevity) output_time += ola_hop_size * playback_rate Functions received a `playback_rate` parameter to check how many samples are needed before iteration. Internal state is only updated when the iteration is actually run, so the speed is allowed to change until enough data is received.
* af_scaletempo2: fix audio artifact on initial WSOLA iterationferreum2023-09-202-7/+20
| | | | | | | | | The first WSOLA iteration overlapped audio with whatever was in the `wsola_output` buffer. This was either silence (if not run before), or old frames (if switching to 1x and back to a different speed). Track the state of the output buffer and memcpy the whole window for the first iteration instead.
* af_scaletempo2: fix audio offset when playing back at 1x speedferreum2023-09-201-9/+13
| | | | | `read_input_buffer` needs to respect the `target_block_index`, otherwise the audio resumes at the wrong position.
* af_scaletempo2: fix inconsistent search block position after initferreum2023-09-201-2/+3
| | | | | | | | | `output_time` is used to set the center of the search block. Init of both `search_block_index` and `output_time` with 0 caused inconsistent search block movement for the first iterations. Initialize with `search_block_center_offset` for consistency with initial `search_block_index`.
* af_scaletempo2: move latency calculation to internal functionferreum2023-09-203-3/+9
|
* af_scaletempo2: fix missing dereference when processing final packetferreum2023-09-201-1/+1
| | | | | Missing dereference was not noticed because assigning 0 to pointer is allowed.
* af_scaletempo2: fix audio-video de-sync caused by speed changesferreum2023-09-201-8/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes #12028 There was an additional issue that audio was always delayed by half the configured search-interval. This was caused by the `out` buffer length not being included in the delay calculation. Notes: - Every WSOLA iteration advances the input buffer by _some amount_, and produces data in the output buffer always of size `ola_hop_size`. - `mp_scaletempo2_fill_buffer` is always called with `ola_hop_size` - Thus, the rendered frames are always cleared immediately after processing, and `num_complete_frames` is 0 in the delay calculation. - The factors contributing to delay are: - the pending samples in the input buffer according to the search block position, and - the pending rendered samples in the output buffer (always empty in practice). The frame_delay code looked like that of the rubberband filter, which might not work for scaletempo2. Sometimes a different amount of input audio was consumed by scaletempo2 than expected. It may have been caused by speed changes being a more dynamic process in scaletempo2. This can be seen by where `playback_rate` is used in `run_one_wsola_iteration`: `playback_rate` is only referenced after the iteration, when updating the time and removing old data from buffers. In scaletempo2, the playback speed is applied by changing the amount the search block is moved. That apparently averages out correctly at constant playback speed, but when the speed changes, the error in this assumption probably spikes. This error accumulated across all speed changes because of the persistent `frame_delay` value. With the removal of the persistent `frame_delay`, there should be no way for the audio to drift off. By deriving the delay from filter buffer positions, and the buffers are filled only as much as needed, the delay always stays within buffer bounds.
* options: transition options from OPT_FLAG to OPT_BOOLChristoph Heinrich2023-02-212-5/+5
| | | | | | c78482045444c488bb7948305d583a55d17cd236 introduced a bool option type as a replacement for the flag type, but didn't actually transition and remove the flag type because it would have been too much mundane work.
* af_scaletempo2: fix crash when the number of channels increasesPeter DeLong2022-09-231-5/+4
| | | | | | | | | | | | | | | | When af_scaletempo2.c:process() detects a format change, it goes back through mp_scaletempo2_init() to reinitialize everything. However, mp_scaletempo2.input_buffer is not necessarily reallocated due to a check in af_scaletempo2_internals.c:resize_input_buffer(). This is a problem if the number of audio channels increases, since without reallocating, the buffer for the new channel(s) will at best point to NULL, and at worst uninitialized memory. Since resize_input_buffer() is only called from two places, pull size check out into mp_scaletempo2_fill_input_buffer(). This allows each caller to decide whether they want to resize or not. We could be smarter about when to reallocate, but that would add a lot of machinery for a case I don't expect to be hit often in practice.
* af_rubberband: add new engine option in rubberband 3.0.0Christoph Heinrich2022-08-031-2/+15
|
* af_lavcac3enc: switch to AVChannelLayout when availableJan Ekström2022-06-141-3/+36
|
* af_lavcac3enc: refactor chmap adding into its own functionJan Ekström2022-06-141-7/+13
| | | | This simplifies ifdeffery with AVChannelLayouts.
* various: remove trailing whitespaceGuido Cella2022-05-143-5/+5
|
* af_lavcac3enc: fix some minor thingssfan52022-01-101-2/+3
| | | | mark an array as static, a typo and a missing free
* af_lavcac3enc: replace deprecated av_init_packet()sfan52022-01-101-11/+17
|
* af_lavcac3enc: fix memory leak on no-opNiklas Haas2021-12-141-16/+19
| | | | | | | | | Simply returning out of this function leaks avpkt, need to always "goto done". Rewrite the logic a bit to make it more clear what's going on (IMO). Fixes #9593
* af_scaletempo2: use gcc vectors to speed up inner loopNiklas Haas2021-05-261-3/+72
| | | | | | | | | | This brings my scaletempo2 benchmark down from ~22s to ~7s on my machine (-march=native), and down to ~11s with a generic compile. Guarded behind an appropriate #ifdef to avoid being ableist against people who have the clinical need to run obscure platforms. Closes #8848
* build: address AVCodec, AVInputFormat, AVOutputFormat const warningssfan52021-05-011-1/+1
| | | | FFmpeg recently changed these to be const on their side.
* af_scaletempo2: fix crash for speed >= 16Dorian Rudolph2021-02-151-9/+13
| | | | | | | The input buffer size was fixed, but the required size depends on the speed. Now the buffer will be resized dynamically. Fixes #8081
* af_scaletempo2: fix bug where speed was not setDorian Rudolph2020-07-271-1/+0
| | | | | | the --speed parameter did not work with mpv --no-config whatever.mp3 --video=no --speed=2 --af=scaletempo2 (https://github.com/mpv-player/mpv/pull/7865#issuecomment-664243401)
* af_scaletempo2: M_PI is always definedwm42020-07-271-4/+0
| | | | I forgot why/how (C99?), but other code also uses it.
* audio: add scaletempo2 filter based on chromiumDorian Rudolph2020-07-273-0/+1095
| | | | | | | | scaletempo2 is a new audio filter for playing back audio at modified speed and is based on chromium commit 51ed77e3f37a9a9b80d6d0a8259e84a8ca635259. It sounds subjectively better than the existing implementions scaletempo and rubberband.
* af_scaletempo: handle obscure integer overflowwm42020-06-021-4/+4
| | | | | Saw it once, not really reproducible. This should fix it, and in any case it's harmless.
* audio: redo video-sync=display-adropwm42020-05-231-0/+114
| | | | | | | | | | | | | | | | | This mode drops or repeats audio data to adapt to video speed, instead of resampling it or such. It was added to deal with SPDIF. The implementation was part of fill_audio_out_buffers() - the entire function is something whose complexity exploded in my face, and which I want to clean up, and this is hopefully a first step. Put it in a filter, and mess with the shitty glue code. It's all sort of roundabout and illogical, but that can be rectified later. The important part is that it works much like the resample or scaletempo filters. For PCM audio, this does not work on samples anymore. This makes it much worse. But for PCM you can use saner mechanisms that sound better. Also, something about PTS tracking is wrong. But not wasting more time on this.
* af_scaletempo: fix theoretical UBwm42020-05-231-1/+2
| | | | | Passing NULL to memset() is undefined behavior, even if the size argument is 0. Could happen on init errors and such.
* options: cleanup .min use for OPT_CHANNELSwm42020-04-091-2/+4
| | | | | | | | Replace use of .min==1 with a proper flag. This is a good idea, because it has nothing to do with numeric limits (also see commit 9d32d62b61547 for how this can go wrong). With this, m_option.min/max are strictly used for numeric limits.
* options: change option macros and all option declarationswm42020-03-184-50/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Change all OPT_* macros such that they don't define the entire m_option initializer, and instead expand only to a part of it, which sets certain fields. This requires changing almost every option declaration, because they all use these macros. A declaration now always starts with {"name", ... followed by designated initializers only (possibly wrapped in macros). The OPT_* macros now initialize the .offset and .type fields only, sometimes also .priv and others. I think this change makes the option macros less tricky. The old code had to stuff everything into macro arguments (and attempted to allow setting arbitrary fields by letting the user pass designated initializers in the vararg parts). Some of this was made messy due to C99 and C11 not allowing 0-sized varargs with ',' removal. It's also possible that this change is pointless, other than cosmetic preferences. Not too happy about some things. For example, the OPT_CHOICE() indentation I applied looks a bit ugly. Much of this change was done with regex search&replace, but some places required manual editing. In particular, code in "obscure" areas (which I didn't include in compilation) might be broken now. In wayland_common.c the author of some option declarations confused the flags parameter with the default value (though the default value was also properly set below). I fixed this with this change.
* options: change how option range min/max is handledwm42020-03-132-5/+6
| | | | | | | | | | | | | | | | | Before this commit, option declarations used M_OPT_MIN/M_OPT_MAX (and some other identifiers based on these) to signal whether an option had min/max values. Remove these flags, and make it use a range implicitly on the condition if min<max is true. This requires care in all cases when only M_OPT_MIN or M_OPT_MAX were set (instead of both). Generally, the commit replaces all these instances with using DBL_MAX/DBL_MIN for the "unset" part of the range. This also happens to fix some cases where you could pass over-large values to integer options, which were silently truncated, but now cause an error. This commit has some higher potential for regressions.
* audio/filter: remove no longer used headerPaul B Mahol2019-10-051-47/+0
|
* audio: remove unreferenced af_lavrresamplewm42019-09-191-112/+0
| | | | | | | | | | | | | | This filter wasn't referenced anywhere and thus was dead code. It should have been in the audio filter list in user_filters.c. This was intended as compatibility wrapper (to avoid breaking old command lines and config files), and has no real use. Apparently I forgot to add it to the filter list (did I even test this shit?), and so it was rotting around for 1.5 years doing nothing (just like myself). Note that users can just use the libavfilter provided filter to force resampling, just that it has a different name and different options. There's also af_format to force inserting auto conversion through the internal f_swsresample filter.
* af_rubberband: reset delay to 0 on resetHector Martin2018-08-251-0/+2
| | | | This fixes A-V drift on seeking
* af_scaletempo: output minimally sized audio framewm42018-02-031-57/+76
| | | | | | | | | | | | | | | | | | | | This helps the filter to adapt much faster to speed changes. Before this commit, the filter just converted and output the full input frame, which could cause problems with large input frames. This was made worse by certain filters like dynaudnorm or loudnorm outputting pretty large frames. This commit changes the filter from trying to convert all input at once to only outputting a single internally filtered frame. Internally, this filter already output data in units of 60ms by default (controlled by the "stride" sub-option), and concatenated as many output frames as necessary to consume all input. Behavior is still kind of bad when inserting the filter. This is because the large frames can be buffered up after the insertion point, so the speed change will be performed with a larger latency. The scaletempo filter can't do anything against this, although it can be fixed by inserting scaletempo as user filter as part of --af.
* audio: rewrite filtering glue codewm42018-01-309-2374/+985
| | | | Use the new filtering code for audio too.
* af_rubberband: add af-command to multiply current pitchVobe2018-01-151-6/+16
| | | | | | | | | | | | | This commit introduces the multiply-pitch af-command. Users may bind keys to this command in order to incrementally adjust the pitch of a track. This will probably mostly be useful for musicians trying to transpose up and down by semi tones without having to calculate the correct ratio beforehand. As an example, here is an input.conf to test this feature: { af-command all multiply-pitch 0.9438743126816935 } af-command all multiply-pitch 1.059463094352953
* af_lavrresample: deprecate this filterwm42018-01-132-2/+12
| | | | | | The future direction might be not having such a user-visible filter at all, similar to how vf_scale went away (or actually, redirects to libavfilter's vf_scale).
* audio: add global options for resampler defaultswm42018-01-133-1/+30
| | | | | | | | This is part of trying to get rid of --af-defaults, and the af resample filter. It requires a complicated mechanism to set the defaults on the resample filter for backwards compatibility.
* Fix various typos in log messagesNicolas F2017-12-031-1/+1
|
* audio: add audio softvol processing to AOwm42017-11-292-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This does what af_volume used to do. Since we couldn't relicense it, just rewrite it. Since we don't have a new filter mechanism yet, and the libavfilter is too inconvenient, do applying the volume gain in ao.c directly. This is done before handling the audio data to the driver. Since push.c runs a separate thread, and pull.c is called asynchronously from the audio driver's thread, the volume value needs to be synchronized. There's no existing central mutex, so do some shit with atomics. Since there's no atomic_float type predefined (which is at least needed when using the legacy wrapper), do some nonsense about reinterpret casting the float value to an int for the purpose of atomic access. Not sure if using memcpy() is undefined behavior, but for now I don't care. The advantage of not using a filter is lower complexity (no filter auto insertion), and lower latency (gain processing is done after our internal audio buffer of at least 200ms). Disavdantages include inability to use native volume control _before_ other filters with custom filter chains, and the need to add new processing for each new sample type. Since this doesn't reuse any of the old GPL code, nor does indirectly rely on it, volume and replaygain handling now works in LGPL mode. How to process the gain is inspired by libavfilter's af_volume (LGPL). In particular, we use exactly the same rounding, and we quantize processing for integer sample types by 256 steps. Some of libavfilter's copyright may or may not apply, but I think not, and it's the same license anyway.
*