From patchwork Wed Jul 19 13:11:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: george@spotify.com X-Patchwork-Id: 4368 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.1.76 with SMTP id 73csp820263vsb; Wed, 19 Jul 2017 06:12:01 -0700 (PDT) X-Received: by 10.223.130.110 with SMTP id 101mr1619995wrb.111.1500469921582; Wed, 19 Jul 2017 06:12:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1500469921; cv=none; d=google.com; s=arc-20160816; b=AJYZ5o4PaKMSc4SHQrOlP0558VEObiyAnHds9wpKu1uA+Ik3/gVfmFT6VBLGFiOnn2 Nj5yCFyS61cnqYIT4GFGlZAkUwQ196mzmPwjDdObOahjsrEFBEtSlAdbeUTxphU5+vqm 9Ag2ed0wqwYHQlP+xCDbKaVmNkDO4iYDIS1YKOYk5r6zSprpDQgv0axH3yKNGIGUWe/w 4ebuXYNddaLelQuW0aNckyb3rtmYSTprtY/KInZitqoZ02ggIJ5Ip77fw4ewE1C/SGrp pyuVs1jqOfNqQF1+iRN9StsoQlbuodf1kef1/Iv7l+J5/D5zNWSWL4jGTo2StzrQ2iVK Mm1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=ygzg3zvnQTQI4CC1x8mqPqSHV9yBtPZ3fo7Sjy6wky8=; b=zbLLmPszdaV8OdY7wKcCqUSN9XajFAA5fa5RQBsYdMGW5YML06aIp4z9Ck9FwlbOJY xHZG8Vp7fZ3pfwXhM0meQHHs+gOGllcBPdazXKFsFNeH51J7HixLXi3MBr8hadVk1P7J /Xx4EY3WCJVJ6k5kjBrRWbkr2JhcasUmiEYZO162r+wUX5pioEJtAUe+iJiCHh5AOXe7 ozy5+rniGC3+tSX1rXUyXTMxHB4jjHEsIarFqJncipe6okEC4c6zAuy4OM2z0aBv4AiE RpAv2ky5GP1d+WZrtsdCYxC27wHRHXdeSjXOq7oEF556wJQwfwG9+jqklggWRhVCuvUJ EfIg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@spotify.com header.b=WqiHqFHp; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=REJECT sp=REJECT dis=QUARANTINE) header.from=spotify.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id h23si4116601wrb.6.2017.07.19.06.12.00; Wed, 19 Jul 2017 06:12:01 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@spotify.com header.b=WqiHqFHp; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=REJECT sp=REJECT dis=QUARANTINE) header.from=spotify.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 26464689890; Wed, 19 Jul 2017 16:11:51 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf0-f41.google.com (mail-lf0-f41.google.com [209.85.215.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AEEBB68831B for ; Wed, 19 Jul 2017 16:11:44 +0300 (EEST) Received: by mail-lf0-f41.google.com with SMTP id d78so128445lfg.3 for ; Wed, 19 Jul 2017 06:11:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=spotify.com; s=google; h=from:to:cc:subject:date:message-id; bh=coDV5tm8vvZxZFJ+NCYSt8oIbE1Q6K2B3RrstxQROgM=; b=WqiHqFHpJvVB9ZKMpFt2OM9HR8y8qJ5xOsjHqEobme4TrSdV7nK8dJo1qip5xm5ddw ohNJFC7OrpQRSLMsKc3zTCDQSPNhGPZ8+VqGzkfRvJvr4hN5JGMWEmJjvlArtjriKMbB Px6v7wmP4+9wENYIEmWBcJ7pqwlU1dbUiykws= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=coDV5tm8vvZxZFJ+NCYSt8oIbE1Q6K2B3RrstxQROgM=; b=VJDCeg9MOCd4gk04rEUQXcQHyKgH97odXGU+pRIn/FcJqmRzceGJ6i9T0tm20V3Pob 6vU0/Ydgge3G3n06oPKMvkYQygB0TeBVl7P62K/uANJiFoni2bMWYNVP1eRsrrDw3mJP yuc2lebROqRMQMP/Esu2b4RYd5+i+iQzwsgVbD5F7Fm/dEOV9HTgOhLmKp4x7mTWD+t7 JnKuHr8c5mL3CzkwDN/TgtSNbV13CvPgj/x4X1UZcRlDPhq5Rp0YvaMI9011mN6WKuxZ 2IagqZNHSJd7EfuGqQ/anfSTZthh2vf2B33Nb1xKgCpDSu/KfYo40HKqFpTn9h6HVlCs fQNA== X-Gm-Message-State: AIVw1137j1kAHg460IVdzU7E/rxAwyq117b1Y0QHvtbpHQWSh2GuFb44 3kIFsaHbFzt8ZzyT1LW/SA== X-Received: by 10.25.18.87 with SMTP id h84mr217947lfi.217.1500469911240; Wed, 19 Jul 2017 06:11:51 -0700 (PDT) Received: from porto.spotify.net ([2a01:2b0:3041:3020:6257:18ff:fe8b:872e]) by smtp.gmail.com with ESMTPSA id e11sm2527lfg.37.2017.07.19.06.11.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Jul 2017 06:11:50 -0700 (PDT) From: george@spotify.com To: ffmpeg-devel@ffmpeg.org Date: Wed, 19 Jul 2017 15:11:44 +0200 Message-Id: <20170719131144.32019-1-george@spotify.com> X-Mailer: git-send-email 2.13.3 Subject: [FFmpeg-devel] [PATCH] avfilter: Add blue and violet noise generation filters X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: George Boyle MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: George Boyle For the blue and violet noise, I took the pink and brown noise respectively and subtracted the offsets instead of adding them. When I eyeball the frequency spectrum of the resulting outputs it looks correct to me, i.e. the blue graph appears to be a mirror image of the pink, and the same can be said of the violet and the brown. I did not do anything else to confirm the correctness. --- doc/filters.texi | 4 +-- libavfilter/asrc_anoisesrc.c | 72 +++++++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 2708fdb1df..dd88636bb9 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4471,8 +4471,8 @@ Specify the duration of the generated audio stream. Not specifying this option results in noise with an infinite length. @item color, colour, c -Specify the color of noise. Available noise colors are white, pink, and brown. -Default color is white. +Specify the color of noise. Available noise colors are white, pink, brown, +blue and violet. Default color is white. @item seed, s Specify a value used to seed the PRNG. diff --git a/libavfilter/asrc_anoisesrc.c b/libavfilter/asrc_anoisesrc.c index be0d5ab6a5..c3d99b3166 100644 --- a/libavfilter/asrc_anoisesrc.c +++ b/libavfilter/asrc_anoisesrc.c @@ -41,24 +41,35 @@ typedef struct ANoiseSrcContext { AVLFG c; } ANoiseSrcContext; +enum NoiseMode { + NM_WHITE, + NM_PINK, + NM_BROWN, + NM_BLUE, + NM_VIOLET, + NM_NB +}; + #define OFFSET(x) offsetof(ANoiseSrcContext, x) #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM static const AVOption anoisesrc_options[] = { - { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 15, INT_MAX, FLAGS }, - { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 15, INT_MAX, FLAGS }, - { "amplitude", "set amplitude", OFFSET(amplitude), AV_OPT_TYPE_DOUBLE, {.dbl = 1.}, 0., 1., FLAGS }, - { "a", "set amplitude", OFFSET(amplitude), AV_OPT_TYPE_DOUBLE, {.dbl = 1.}, 0., 1., FLAGS }, - { "duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, FLAGS }, - { "d", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, FLAGS }, - { "color", "set noise color", OFFSET(color), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 2, FLAGS, "color" }, - { "colour", "set noise color", OFFSET(color), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 2, FLAGS, "color" }, - { "c", "set noise color", OFFSET(color), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 2, FLAGS, "color" }, - { "white", 0, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, FLAGS, "color" }, - { "pink", 0, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, FLAGS, "color" }, - { "brown", 0, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, FLAGS, "color" }, - { "seed", "set random seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64 = -1}, -1, UINT_MAX, FLAGS }, - { "s", "set random seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64 = -1}, -1, UINT_MAX, FLAGS }, + { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 15, INT_MAX, FLAGS }, + { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 15, INT_MAX, FLAGS }, + { "amplitude", "set amplitude", OFFSET(amplitude), AV_OPT_TYPE_DOUBLE, {.dbl = 1.}, 0., 1., FLAGS }, + { "a", "set amplitude", OFFSET(amplitude), AV_OPT_TYPE_DOUBLE, {.dbl = 1.}, 0., 1., FLAGS }, + { "duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, FLAGS }, + { "d", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, FLAGS }, + { "color", "set noise color", OFFSET(color), AV_OPT_TYPE_INT, {.i64 = 1}, 0, NM_NB - 1, FLAGS, "color" }, + { "colour", "set noise color", OFFSET(color), AV_OPT_TYPE_INT, {.i64 = 1}, 0, NM_NB - 1, FLAGS, "color" }, + { "c", "set noise color", OFFSET(color), AV_OPT_TYPE_INT, {.i64 = 0}, 0, NM_NB - 1, FLAGS, "color" }, + { "white", 0, 0, AV_OPT_TYPE_CONST, {.i64 = NM_WHITE}, 0, 0, FLAGS, "color" }, + { "pink", 0, 0, AV_OPT_TYPE_CONST, {.i64 = NM_PINK}, 0, 0, FLAGS, "color" }, + { "brown", 0, 0, AV_OPT_TYPE_CONST, {.i64 = NM_BROWN}, 0, 0, FLAGS, "color" }, + { "blue", 0, 0, AV_OPT_TYPE_CONST, {.i64 = NM_BLUE}, 0, 0, FLAGS, "color" }, + { "violet", 0, 0, AV_OPT_TYPE_CONST, {.i64 = NM_VIOLET}, 0, 0, FLAGS, "color" }, + { "seed", "set random seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64 = -1}, -1, UINT_MAX, FLAGS }, + { "s", "set random seed", OFFSET(seed), AV_OPT_TYPE_INT64, {.i64 = -1}, -1, UINT_MAX, FLAGS }, { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS }, { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS }, {NULL} @@ -121,6 +132,22 @@ static double pink_filter(double white, double *buf) return pink * 0.11; } +static double blue_filter(double white, double *buf) +{ + double blue; + + /* Same as pink_filter but subtract the offsets rather than add */ + buf[0] = 0.0555179 * white - 0.99886 * buf[0]; + buf[1] = 0.0750759 * white - 0.99332 * buf[1]; + buf[2] = 0.1538520 * white - 0.96900 * buf[2]; + buf[3] = 0.3104856 * white - 0.86650 * buf[3]; + buf[4] = 0.5329522 * white - 0.55000 * buf[4]; + buf[5] = -0.016898 * white + 0.76160 * buf[5]; + blue = buf[0] + buf[1] + buf[2] + buf[3] + buf[4] + buf[5] + buf[6] + white * 0.5362; + buf[6] = white * 0.115926; + return blue * 0.11; +} + static double brown_filter(double white, double *buf) { double brown; @@ -130,6 +157,15 @@ static double brown_filter(double white, double *buf) return brown * 3.5; } +static double violet_filter(double white, double *buf) +{ + double violet; + + violet = ((0.02 * white) - buf[0]) / 1.02; + buf[0] = violet; + return violet * 3.5; +} + static av_cold int config_props(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; @@ -144,9 +180,11 @@ static av_cold int config_props(AVFilterLink *outlink) s->duration = av_rescale(s->duration, s->sample_rate, AV_TIME_BASE); switch (s->color) { - case 0: s->filter = white_filter; break; - case 1: s->filter = pink_filter; break; - case 2: s->filter = brown_filter; break; + case NM_WHITE: s->filter = white_filter; break; + case NM_PINK: s->filter = pink_filter; break; + case NM_BROWN: s->filter = brown_filter; break; + case NM_BLUE: s->filter = blue_filter; break; + case NM_VIOLET: s->filter = violet_filter; break; } return 0;