Hi,

On Fri, 2017-08-18 at 12:16 -0400, Lyude Paul wrote:
> One more small formatting change
> 
> On Thu, 2017-08-17 at 19:05 +0300, Paul Kocialkowski wrote:
> > This introduces an audio library, with dedicated helpers for both
> > generating signals and detecting peak frequencies in a signal.
> > 
> > This library paves the way for testing audio going through display
> > connectors, such as HDMI.
> > 
> > Signed-off-by: Paul Kocialkowski <[email protected]>
> > ---
> >  .../intel-gpu-tools/intel-gpu-tools-docs.xml       |   1 +
> >  lib/Makefile.am                                    |   2 +
> >  lib/igt.h                                          |   1 +
> >  lib/igt_audio.c                                    | 326
> > +++++++++++++++++++++
> >  lib/igt_audio.h                                    |  47 +++
> >  5 files changed, 377 insertions(+)
> >  create mode 100644 lib/igt_audio.c
> >  create mode 100644 lib/igt_audio.h
> > 
> > diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> > b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> > index f88afd2a..c77159cf 100644
> > --- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> > +++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> > @@ -16,6 +16,7 @@
> >    <chapter>
> >      <title>API Reference</title>
> >      <xi:include href="xml/drmtest.xml"/>
> > +    <xi:include href="xml/igt_audio.xml"/>
> >      <xi:include href="xml/igt_aux.xml"/>
> >      <xi:include href="xml/igt_chamelium.xml"/>
> >      <xi:include href="xml/igt_core.xml"/>
> > diff --git a/lib/Makefile.am b/lib/Makefile.am
> > index 9c932d6f..5ea08314 100644
> > --- a/lib/Makefile.am
> > +++ b/lib/Makefile.am
> > @@ -33,6 +33,8 @@ if HAVE_GSL
> >  lib_source_list +=         \
> >     igt_frame.c             \
> >     igt_frame.h             \
> > +   igt_audio.c             \
> > +   igt_audio.h             \
> >     $(NULL)
> >  endif
> >  
> > diff --git a/lib/igt.h b/lib/igt.h
> > index d16a4991..a75d2db7 100644
> > --- a/lib/igt.h
> > +++ b/lib/igt.h
> > @@ -35,6 +35,7 @@
> >  #include "igt_dummyload.h"
> >  #include "igt_fb.h"
> >  #include "igt_frame.h"
> > +#include "igt_audio.h"
> >  #include "igt_gt.h"
> >  #include "igt_kms.h"
> >  #include "igt_pm.h"
> > diff --git a/lib/igt_audio.c b/lib/igt_audio.c
> > new file mode 100644
> > index 00000000..527a4930
> > --- /dev/null
> > +++ b/lib/igt_audio.c
> > @@ -0,0 +1,326 @@
> > +/*
> > + * Copyright © 2017 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person
> > obtaining a
> > + * copy of this software and associated documentation files (the
> > "Software"),
> > + * to deal in the Software without restriction, including without
> > limitation
> > + * the rights to use, copy, modify, merge, publish, distribute,
> > sublicense,
> > + * and/or sell copies of the Software, and to permit persons to
> > whom
> > the
> > + * Software is furnished to do so, subject to the following
> > conditions:
> > + *
> > + * The above copyright notice and this permission notice (including
> > the next
> > + * paragraph) shall be included in all copies or substantial
> > portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
> > EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
> > DAMAGES
> > OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> > ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + * Authors:
> > + *  Paul Kocialkowski <[email protected]>
> > + */
> > +
> > +#include "config.h"
> > +
> > +#include <math.h>
> > +#include <gsl/gsl_fft_real.h>
> > +
> > +#include "igt.h"
> > +
> > +#define FREQS_MAX  8
> > +
> > +/**
> > + * SECTION:igt_audio
> > + * @short_description: Library for audio-related tests
> > + * @title: Audio
> > + * @include: igt_audio.h
> > + *
> > + * This library contains helpers for audio-related tests. More
> > specifically,
> > + * it allows generating additions of sine signals as well as
> > detecting them.
> > + */
> > +
> > +struct audio_signal_freq {
> > +   int freq;
> > +
> > +   short *period;
> > +   int frames;
> > +   int offset;
> > +};
> > +
> > +struct audio_signal {
> > +   int channels;
> > +   int sampling_rate;
> > +
> > +   struct audio_signal_freq freqs[FREQS_MAX];
> > +   int freqs_count;
> > +};
> > +
> > +/**
> > + * audio_signal_init:
> > + * @channels: The number of channels to use for the signal 
> > + * @sampling_rate: The sampling rate to use for the signal
> > + *
> > + * Allocate and initialize an audio signal structure with the given
> > parameters.
> > + *
> > + * Returns: A newly-allocated audio signal structure
> > + */
> > +struct audio_signal *audio_signal_init(int channels, int
> > sampling_rate)
> > +{
> > +   struct audio_signal *signal;
> > +
> > +   signal = malloc(sizeof(struct audio_signal));
> > +   memset(signal, 0, sizeof(struct audio_signal));
> > +
> > +   signal->sampling_rate = sampling_rate;
> > +   signal->channels = channels;
> > +
> > +   return signal;
> > +}
> > +
> > +/**
> > + * audio_signal_add_frequency:
> > + * @signal: The target signal structure
> > + * @frequency: The frequency to add to the signal
> > + *
> > + * Add a frequency to the signal.
> > + *
> > + * Returns: An integer equal to zero for success and negative for
> > failure
> > + */
> > +int audio_signal_add_frequency(struct audio_signal *signal, int
> > frequency)
> > +{
> > +   int index = signal->freqs_count;
> > +
> > +   if (index == FREQS_MAX)
> > +           return -1;
> > +
> > +   /* Stay within the Nyquist–Shannon sampling theorem. */
> > +   if (frequency > signal->sampling_rate / 2)
> > +           return -1;
> > +
> > +   /* Clip the frequency to an integer multiple of the
> > sampling
> > rate.
> > +    * This to be able to store a full period of it and use
> > that
> > for
> > +    * signal generation, instead of recurrent calls to sin().
> > +    */
> > +   frequency = signal->sampling_rate / (signal->sampling_rate
> > /
> > frequency);
> > +
> > +   igt_debug("Adding test frequency %d\n", frequency);
> > +
> > +   signal->freqs[index].freq = frequency;
> > +   signal->freqs[index].frames = 0;
> > +   signal->freqs[index].offset = 0;
> > +   signal->freqs_count++;
> > +
> > +   return 0;
> > +}
> > +
> > +/**
> > + * audio_signal_synthesize:
> > + * @signal: The target signal structure
> > + *
> > + * Synthesize the data tables for the audio signal, that can later
> > be used
> > + * to fill audio buffers. The resources allocated by this function
> > must be
> > + * freed with a call to audio_signal_clean when the signal is no
> > longer used.
> > + */
> > +void audio_signal_synthesize(struct audio_signal *signal)
> > +{
> > +   short *period;
> > +   double value;
> > +   int frames;
> > +   int freq;
> > +   int i, j;
> > +
> > +   if (signal->freqs_count == 0)
> > +           return;
> > +
> > +   for (i = 0; i < signal->freqs_count; i++) {
> > +           freq = signal->freqs[i].freq;
> > +           frames = signal->sampling_rate / freq;
> > +
> > +           period = calloc(1, frames * sizeof(short));
> > +
> > +           for (j = 0; j < frames; j++) {
> > +                   value = 2.0 * M_PI * freq / signal-
> > > sampling_rate * j;
> > 
> > +                   value = sin(value) * SHRT_MAX / signal-
> > > freqs_count;
> > 
> > +
> > +                   period[j] = (short) value; 
> > +           }
> > +
> > +           signal->freqs[i].period = period;
> > +           signal->freqs[i].frames = frames;
> > +   }
> > +}
> > +
> > +/**
> > + * audio_signal_synthesize:
> > + * @signal: The target signal structure
> > + *
> > + * Free the resources allocated by audio_signal_synthesize and
> > remove
> > + * the previously-added frequencies.
> > + */
> > +void audio_signal_clean(struct audio_signal *signal)
> > +{
> > +   int i;
> > +
> > +   for (i = 0; i < signal->freqs_count; i++) {
> > +           if (signal->freqs[i].period)
> > +                   free(signal->freqs[i].period);
> > +
> > +           memset(&signal->freqs[i], 0, sizeof(struct
> > audio_signal_freq));
> > +   }
> > +
> > +   signal->freqs_count = 0;
> > +}
> > +
> > +/**
> > + * audio_signal_fill:
> > + * @signal: The target signal structure
> > + * @buffer: The target buffer to fill
> > + * @frames: The number of frames to fill
> > + *
> > + * Fill the requested number of frames to the target buffer with
> > the
> > audio
> > + * signal data (in interleaved S16_LE format), at the requested
> > sampling rate
> > + * and number of channels.
> > + */
> > +void audio_signal_fill(struct audio_signal *signal, short *buffer,
> > int frames)
> > +{
> > +   short *destination;
> > +   short *source;
> > +   int total;
> > +   int freq_frames;
> > +   int freq_offset;
> > +   int count;
> > +   int i, j, k;
> > +
> > +   memset(buffer, 0, sizeof(short) * signal->channels *
> > frames);
> > +
> > +   for (i = 0; i < signal->freqs_count; i++) {
> > +           total = 0;
> > +
> > +           while (total < frames) {
> > +                   freq_frames = signal->freqs[i].frames;
> > +                   freq_offset = signal->freqs[i].offset;
> > +
> > +                   source = signal->freqs[i].period +
> > freq_offset;
> > +                   destination = buffer + total * signal-
> > > channels;
> > 
> > +
> > +                   count = freq_frames - freq_offset;
> > +                   if (count > (frames - total))
> > +                           count = frames - total;
> > +
> > +                   freq_offset += count;
> > +                   freq_offset %= freq_frames;
> > +
> > +                   signal->freqs[i].offset = freq_offset;
> > +
> > +                   for (j = 0; j < count; j++) {
> > +                           for (k = 0; k < signal->channels;
> > k++) {
> > +                                   destination[j * signal-
> > > channels + k] += source[j];
> > 
> > +                           }
> > +                   }
> > +
> > +                   total += count;
> > +           }
> > +   }
> > +}
> > +
> > +/**
> > + * audio_signal_detect:
> > + * @signal: The target signal structure
> > + * @channels: The input data's number of channels
> > + * @sampling_rate: The input data's sampling rate
> > + * @buffer: The input data's buffer
> > + * @frames: The input data's number of frames
> > + *
> > + * Detect that the frequencies specified in @signal, and only
> > those,
> > are
> > + * present in the input data. The input data's format is required
> > to
> > be S16_LE.
> > + *
> > + * Returns: A boolean indicating whether the detection was
> > successful
> > + */
> > +bool audio_signal_detect(struct audio_signal *signal, int channels,
> > +                    int sampling_rate, short *buffer, int
> > frames)
> > +{
> > +   double data[frames];
> > +   int amplitude[frames / 2];
> > +   bool detected[signal->freqs_count];
> > +   int threshold;
> > +   bool above;
> > +   int error;
> > +   int freq;
> > +   int max;
> > +   int c, i, j;
> > +
> > +   /* Allowed error in Hz due to FFT step. */
> > +   error = sampling_rate / frames;
> > +
> > +   for (c = 0; c < channels; c++) {
> > +           for (i = 0; i < frames; i++)
> > +                   data[i] = (double) buffer[i * channels +
> > c];
> > +
> > +           gsl_fft_real_radix2_transform(data, 1, frames);
> > +
> > +           max = 0;
> > +
> > +           for (i = 0; i < frames / 2; i++) {
> > +                   amplitude[i] = sqrt(data[i] * data[i] +
> > +                                             data[frames - i]
> > *
> > +                                             data[frames -
> > i]);
> 
> More indenting fixes? not sure if this one is just a result of it
> getting formatted as an email.

This one was a legit mistake, good catch!

> > +                   if (amplitude[i] > max)
> > +                           max = amplitude[i];
> > +           }
> > +
> > +           for (i = 0; i < signal->freqs_count; i++)
> > +                   detected[i] = false;
> > +
> > +           threshold = max / 2;
> > +           above = false;
> > +           max = 0;
> > +
> > +           for (i = 0; i < frames / 2; i++) {
> > +                   if (amplitude[i] > threshold)
> > +                           above = true;
> > +
> > +                   if (above) {
> > +                           if (amplitude[i] < threshold) {
> > +                                   above = false;
> > +                                   max = 0;
> > +
> > +                                   for (j = 0; j < signal-
> > > freqs_count; j++) {
> > 
> > +                                           if (signal-
> > > freqs[j].freq >
> > 
> > +                                               freq - error &&
> > +                                               signal-
> > > freqs[j].freq <
> > 
> > +                                               freq + error) {
> > +                                                   detected[j]
> > = true;
> > +                                                   break;
> > +                                           }
> > +                                   }
> > +
> > +                                   /* Detected frequency was
> > not generated. */
> > +                                   if (j == signal-
> > > freqs_count) {
> > 
> > +                                           igt_debug("Detected
> > additional frequency: %d\n",
> > +                                                     freq);
> > +                                           return false;
> > +                                   }
> > +                           }
> > +
> > +                           if (amplitude[i] > max) {
> > +                                   max = amplitude[i];
> > +                                   freq = sampling_rate * i /
> > frames;
> > +                           }
> > +                   }
> > +           }
> > +
> > +           for (i = 0; i < signal->freqs_count; i++) {
> > +                   if (!detected[i]) {
> > +                           igt_debug("Missing frequency:
> > %d\n",
> > +                                     signal->freqs[i].freq);
> > +                           return false;
> > +                   }
> > +           }
> > +   }
> > +
> > +   return true;
> > +}
> > diff --git a/lib/igt_audio.h b/lib/igt_audio.h
> > new file mode 100644
> > index 00000000..507e7ab9
> > --- /dev/null
> > +++ b/lib/igt_audio.h
> > @@ -0,0 +1,47 @@
> > +/*
> > + * Copyright © 2017 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person
> > obtaining a
> > + * copy of this software and associated documentation files (the
> > "Software"),
> > + * to deal in the Software without restriction, including without
> > limitation
> > + * the rights to use, copy, modify, merge, publish, distribute,
> > sublicense,
> > + * and/or sell copies of the Software, and to permit persons to
> > whom
> > the
> > + * Software is furnished to do so, subject to the following
> > conditions:
> > + *
> > + * The above copyright notice and this permission notice (including
> > the next
> > + * paragraph) shall be included in all copies or substantial
> > portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
> > EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
> > DAMAGES
> > OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> > ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + * Authors:
> > + *  Paul Kocialkowski <[email protected]>
> > + */
> > +
> > +#ifndef IGT_AUDIO_H
> > +#define IGT_AUDIO_H
> > +
> > +#ifdef HAVE_CONFIG_H
> > +#include "config.h"
> > +#endif
> > +
> > +#include "igt.h"
> > +#include <stdbool.h>
> > +
> > +struct audio_signal;
> > +
> > +struct audio_signal *audio_signal_init(int channels, int
> > sampling_rate);
> > +int audio_signal_add_frequency(struct audio_signal *signal, int
> > frequency);
> > +void audio_signal_synthesize(struct audio_signal *signal);
> > +void audio_signal_clean(struct audio_signal *signal);
> > +void audio_signal_fill(struct audio_signal *signal, short *buffer,
> > int frames);
> > +bool audio_signal_detect(struct audio_signal *signal, int channels,
> > +                    int sampling_rate, short *buffer, int
> > frames);
> > +
> > +#endif
-- 
Paul Kocialkowski <[email protected]>
Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo, Finland
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to