On 27-11-07 03:43, Mark Constable wrote:

How about a copyright, license, contact and version info,
and a bit of a readme in the header comments ?

Heh, public domain. Given that its expression is dictated by mathematics on
the one hand and the S16_LE format on the other, I'd have difficulty finding
anything copyrightable in there...

I'd like to package it and maybe try to wrap some kind
of simple Qt4 GUI hearing test applet around it, one day.

But, updated as requested. If you snip the option parsing you're ofcourse
left with basically 2 lines so you might want to simply lift those into
whatever other program.

It would be really cool to have some proggie that could
be run, every 3 months or so, to test ones hearing and
keep the results in SQLite (or online) and also provide
some kind of Jack/ALSA based EQ bias based on the stored
results. Like, ultra cool.

That does sound useful. Equalizers are mostly useless due to almost noone
having the costly measuring equipment needed to make them use _ful_.

Ofcourse, results would be fully local to the specific combination of user
and used card/amplifier/headphones/speakers...

I recently got some good cans and a headphone amp and I am amazed at what
I can now hear, and NOT hear, so it would be genuinely useful to have a
custom EQ thingie that I could apply to any computer (at least) generated
music that adapted to my failing ears over the years.

A point is that these kind of "hearing tests" are almost> useless in
absolute terms but are indeed meaningful when tested and accumulated
results are compared with for any particular individual. The consistent
mean is to set up the listening environment to just be able to hear 1khz at (about, I forget the right level) -50db and then run the rest of the
tests from that reference. As long as this reference marker is used for
each testing session then the results can be reliable for that
individual.

Right. One page up from the samples page you posted earlier was a "personal
dB curve" page that was useful in that respect:

http://www.phys.unsw.edu.au/jw/hearing.html

But yes, nice concept. If you indeed look at anything of the sort, keep us
updated...

Rene.


/*
 * Generate a stereo S16_LE sine at settable rate, frequency and dBFS
 *
 * Public Domain 2007, Rene Herman <[EMAIL PROTECTED]>
 *
 * gcc -W -Wall -Os -o sine sine.c -lm
 *
 * This program outputs a raw S16_LE stereo PCM sine wave to stdout at
 * adjustable sampling rate, frequency and loudness. Its intended use
 * is through something like
 *
 *      $ sine | aplay -D hw:0 -f cd
 *
 * or more generally through something like
 *
 *      $ sine -r 48000 -f 4000 -d -45 | aplay -D hw:1 -f dat
 *
 * THIS PROGRAM GENERATES LOUD SOUND BY DEFAULT AND SHOULD BE USED WITH
 * CAUTION.
 *
 * Most sound setups are perfectly capable of damaging your hearing and
 * certainly through headphones. Be suitably aware of this and do not
 * use this program, at whatever frequency, without at least initially
 * adjusting any (on or off soundcard) amplification down.
 *
 * General use:
 *
 * sine [-r <rate>] [-f <freq>] [-d <dbfs>]
 *
 * -r   Set sampling rate. Limited to between 8000 and 192000 and
 *      with 44100 (the CD rate) as default.
 *
 * -f   The sine frequency in Hz. Limited to between 20 and the
 *      the minimum of 30000 and half the sampling rate (that is,
 *      the Nyquist frequency) and with 440 as default.
 *
 * -d   The loudness in dBFS (dB Full Scale) with 0 dBFS as default.
 *
 * 0 dBFS means maximum power, translating to a maximum amplitude sine
 * with every halving of amplitude causing a 20*log_10(2) (approximately
 * 6.02) decrease in dB. The dynamic range of 16-bit PCM is therefore
 * approximately 96 dB, from -96 dBFS (quietest) upto 0 dbFS (loudest).
 *
 * Also note that the ALSA "default" device may resample and might as
 * such interfere with any tests. Its adviced that you use the "hw"
 * devices with aplay unless you know you don't want/need to.
 *
 * The program is suitably unhelpful when you provide it with out of
 * bounds values. Feel free to improve it. It was only intended as a
 * quick and tiny utility but could perhaps be instructive.
 *
 * Comments might be welcome at the above mentioned email address.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>

#include <unistd.h>

#define RATE_MIN        8000
#define RATE_MAX        192000

#define FREQ_MIN        20
#define FREQ_MAX        30000

#define DBFS_MIN        -((16 * 20 * M_LN2) / M_LN10) /* -96 */
#define DBFS_MAX        0

#define RATE            44100
#define FREQ            440
#define DBFS            0

static inline uint16_t le(uint16_t val)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
        return val;
#else
        return bswap_16(val);
#endif
}

int main(int argc, char *argv[])
{
        int rate = RATE;
        int freq = FREQ;

        double dbfs = DBFS;
        double ampl;

        int i;
       
        while ((i = getopt(argc, argv, "r:f:d:")) != -1) {
                char *endptr;

                switch (i) {
                case 'r':
                        rate = strtol(optarg, &endptr, 0);
                        if (rate < RATE_MIN || rate > RATE_MAX || *endptr)
                                goto usage;
                        break;
                case 'f':
                        freq = strtol(optarg, &endptr, 0);
                        if (freq < FREQ_MIN || freq > FREQ_MAX || *endptr)
                                goto usage;
                        break;
                case 'd':
                        dbfs = strtod(optarg, &endptr);
                        if (dbfs < DBFS_MIN || dbfs > DBFS_MAX || *endptr)
                                goto usage;
                        break;
                default:
                        return EXIT_FAILURE;
                }
        }

        if (rate < 2 * freq) {
usage:
                printf("usage: %s [-r <rate>] [-f <freq>] [-d <dbfs>]\n", 
argv[0]);
                return EXIT_FAILURE;
        }

        ampl = 32767 * pow(10, dbfs / 20); /* 32767 / pow(10, -dbfs / 20) */
        while (1)
                for (i = 0; i < rate; i++) {
                        uint16_t sample = le(ampl * sin(((2 * i * freq) * M_PI) 
/ rate));

                        write(STDOUT_FILENO, &sample, sizeof sample);
                        write(STDOUT_FILENO, &sample, sizeof sample);
                }

        return EXIT_SUCCESS;
}


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Alsa-user mailing list
Alsa-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-user

Reply via email to