{"id":20461857,"url":"https://github.com/kripton/audio-declipper","last_synced_at":"2025-07-25T13:03:39.701Z","repository":{"id":5174330,"uuid":"6348074","full_name":"kripton/audio-declipper","owner":"kripton","description":"Proof-of-concept (or more) to declip sample-based audio files","archived":false,"fork":false,"pushed_at":"2012-10-23T13:06:31.000Z","size":228,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-26T22:51:17.347Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"ros/rosdistro","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kripton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-10-23T06:54:17.000Z","updated_at":"2023-08-06T20:30:37.000Z","dependencies_parsed_at":"2022-07-06T05:01:27.928Z","dependency_job_id":null,"html_url":"https://github.com/kripton/audio-declipper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kripton%2Faudio-declipper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kripton%2Faudio-declipper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kripton%2Faudio-declipper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kripton%2Faudio-declipper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kripton","download_url":"https://codeload.github.com/kripton/audio-declipper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248671287,"owners_count":21143061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T12:28:40.047Z","updated_at":"2025-04-13T06:20:39.765Z","avatar_url":"https://github.com/kripton.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"audio-declipper\n===============\n\nProof-of-concept (or more) to declip sample-based audio files\n\nAbstract\n--------\n\nThis tool was created by the need to declip recorded wave-files that \nwere recorded with a little too high gain. Currently it uses linear \ninterpolation which is not the most ideal thing we could do but \nsine-based interpolation is planned.\n\nThe idea behind\n---------------\n\nIn the analog world, things are quite simple. We use voltage to transfer signals \nfrom one system to another using a defined reference level as 0dB. Voltages \nwill be smaller or maybe larger than the reference level. Whether the receiving \nsystem can safely handle or cope with the input voltage is another story but \ntheoretically it could be pretty high.\n\nIn the digital world, we need to set a fixed upper level since computers \ncannot calculate with arbitrary high numbers (I'm talking about integers here \nas we get it from our audio interface. When using floats as internal \nrepresentation, we could go higher but saving this to a file is again \ncritical). Everything above 0dB is \"clipped\", meaning it just won't go higher \nand stay on the highest possible value. If you have many or large parts your \naudio-material will be distorted. \n\nSo what if we could go higher? That is what I want to try with this tool. \nTo get more headroom (\"space to our upper limit 0dB\") we divide every sample \nfrom the source by 2. _This will reduce your audio's resolution by 1 bit!_ \nAfterwards, the samples that were clipped before are re-calculated. Currently, \nlinear interpolation is used which makes the waveform a straight whereby the \nslope is defined by the sample right before and right after the clip. For the \nfuture, a since-based interpolation is planned which might deliver better \n(closer to the lost, original information).\n\nIf there are longer durations of clipping, the linear interpolation might still \ndeliver clipped audio. In this case you can run the declipper again (and loose \nanother bit of your audio's resolution :P).\n\nMagic?\n------\n\nA magic tool to de-clip audio files? Surely not! What got lost once (during \nrecording) cannot be restored. Furthermore, you loose one bit of \nresolution (granularity) of your input on every run.\n\nSo how do we do it?\n-------------------\n\nWe open the audio file using the libsndfile (means we can read anything supported \nby that library on your system and as long as the file is _mono (one channel only)_. \n\n### Linear interpolation:\nThen we scan through the samples, checking if it has been clipped. If so, we \ncalculate the first slope from the last sample before the clip and the first \nclipped sample and the second slope from the last clipped sample to the first \nnon-clipped sample. Then we divide the length of the clipped samples into \ntwo parts. If the length is odd, the sample in the middle of the clipped region \nis calculated from the second half. Now the tool calculates a new value for \nevery clipped sample using its position in the clipped region and the slope \nused for the half the sample is in.\n\nAll samples are then multiplied by 0.5 (divided by 2) and written to an output \nfile _which is always a float WAVE file, no matter what the input format was_.\n\nHow are the results?\n--------------------\n\nI made some screenshots showing audacity and three short snippets from an audio \nfile that was normalized first and then ampified by 12dB to create clipping. \nThe input is shown above and the output is shown underneath it.\n_No real-world tests have been done yet as this is a proof-of-concept for now_\n\nFurther Ideas\n-------------\n\n- Sine-based interpolation\n- use buffered instead of single-sample procession through the file\n- command line parameters for configuration\n- (more output formats?)\n- (multi-channel support? maybe: coupled changing of all channels or independent? configurable?)\n- LADSPA/LV2-plugin? (achievable latency: 2x buffer size. Maybe not relly realtime).\n\nInstallation\n------------\n\nDependencies:\n- libsndfile (+ headers)\n- Qt4 (QtCore is enough) (+ headers and qmake)\n\nCheckout the repo, cd into it, run \"qmake .\" and \"make\".\n\nIf everything worked okay: \"./audio-declipper testfile.wav\"\n\n\nFurther notes\n-------------\n\nBy now (thanks to Georg on the linux-audio-user mailing list) I've learned \nthat there's xiph.org's postfish which includes a nice declipper. That one \nuses frequency-analysis via FFTW to restore the lost samples:\nhttps://svn.xiph.org/trunk/postfish\n\nComparison to the linear declipper is in the \"results\"-folder, named banjo.png\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkripton%2Faudio-declipper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkripton%2Faudio-declipper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkripton%2Faudio-declipper/lists"}