mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-03 11:12:27 +00:00
Add debug log to cosmoaudio and add examples
This commit is contained in:
parent
a5c0189bf6
commit
0f3457c172
38 changed files with 504 additions and 371 deletions
133
examples/loudness.c
Normal file
133
examples/loudness.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include <cosmoaudio.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* @fileoverview prints ascii meter of microphone loudness
|
||||
*
|
||||
* 0. -60 dB is nearly silent, barely audible, even in a quiet room
|
||||
* 1. -50 dB is very quiet background sounds
|
||||
* 2. -40 dB is quiet ambient noise
|
||||
* 3. -30 dB is clear but soft sounds
|
||||
* 4. -20 dB is moderate volume, comfortable for extended listening
|
||||
* 5. -10 dB is fairly loud, but not uncomfortable
|
||||
* 6. -6 dB is loud, but not at full volume
|
||||
* 7. -3 dB is very loud, approaching system limits
|
||||
* 8. -1 dB is extremely loud, just below maximum
|
||||
* 9. -0 dB is maximum volume without distortion
|
||||
*/
|
||||
|
||||
#define SAMPLING_RATE 44100
|
||||
#define ASCII_METER_WIDTH 20
|
||||
#define FRAMES_PER_SECOND 30
|
||||
#define MIN_DECIBEL -60
|
||||
#define MAX_DECIBEL 0
|
||||
#define DEBUG_LOG 1
|
||||
|
||||
sig_atomic_t g_done;
|
||||
|
||||
void on_signal(int sig) {
|
||||
g_done = 1;
|
||||
}
|
||||
|
||||
// computes root of mean squares
|
||||
double rms(float* p, int n) {
|
||||
double s = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
s += p[i] * p[i];
|
||||
return sqrt(s / n);
|
||||
}
|
||||
|
||||
// converts rms to decibel
|
||||
double rms_to_db(double rms) {
|
||||
double db = 20 * log10(rms);
|
||||
db = fmin(db, MAX_DECIBEL);
|
||||
db = fmax(db, MIN_DECIBEL);
|
||||
return db;
|
||||
}
|
||||
|
||||
int main() {
|
||||
signal(SIGINT, on_signal);
|
||||
|
||||
// how many samples should we process at once
|
||||
int chunkFrames = SAMPLING_RATE / FRAMES_PER_SECOND;
|
||||
|
||||
// configure cosmo audio
|
||||
struct CosmoAudioOpenOptions cao = {0};
|
||||
cao.sizeofThis = sizeof(struct CosmoAudioOpenOptions);
|
||||
cao.deviceType = kCosmoAudioDeviceTypeCapture;
|
||||
cao.sampleRate = SAMPLING_RATE;
|
||||
cao.bufferFrames = chunkFrames * 2;
|
||||
cao.debugLog = DEBUG_LOG;
|
||||
cao.channels = 1;
|
||||
|
||||
// connect to microphone
|
||||
int status;
|
||||
struct CosmoAudio* ca;
|
||||
status = cosmoaudio_open(&ca, &cao);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to open microphone: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// allocate memory for audio work area
|
||||
float* chunk = malloc(chunkFrames * sizeof(float));
|
||||
if (!chunk) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (!g_done) {
|
||||
|
||||
// wait for full chunk of audio to become available
|
||||
int need_in_frames = chunkFrames;
|
||||
status = cosmoaudio_poll(ca, &need_in_frames, NULL);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to poll microphone: %d\n", status);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// read audio frames from microphone ring buffer
|
||||
status = cosmoaudio_read(ca, chunk, chunkFrames);
|
||||
if (status != chunkFrames) {
|
||||
fprintf(stderr, "failed to read microphone: %d\n", status);
|
||||
return 3;
|
||||
}
|
||||
|
||||
// convert audio chunk to to ascii meter
|
||||
char s[ASCII_METER_WIDTH + 1] = {0};
|
||||
double db = rms_to_db(rms(chunk, chunkFrames));
|
||||
double db_range = MAX_DECIBEL - MIN_DECIBEL;
|
||||
int filled_length = (db - MIN_DECIBEL) / db_range * ASCII_METER_WIDTH;
|
||||
for (int i = 0; i < ASCII_METER_WIDTH; ++i) {
|
||||
if (i < filled_length) {
|
||||
s[i] = '=';
|
||||
} else {
|
||||
s[i] = ' ';
|
||||
}
|
||||
}
|
||||
printf("\r%s| %+6.2f dB", s, db);
|
||||
fflush(stdout);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// clean up resources
|
||||
status = cosmoaudio_close(ca);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to close microphone: %d\n", status);
|
||||
return 5;
|
||||
}
|
||||
free(chunk);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue