mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +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
|
@ -18,7 +18,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/audio/cosmoaudio/cosmoaudio.h"
|
||||
#include "dsp/audio/describe.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -201,7 +203,7 @@ static void *cosmoaudio_dlopen(const char *name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cosmoaudio_setup(void) {
|
||||
static void cosmoaudio_setup_impl(void) {
|
||||
void *handle;
|
||||
if (IsOpenbsd())
|
||||
return; // no dlopen support yet
|
||||
|
@ -239,6 +241,12 @@ WeAreGood:
|
|||
g_audio.poll = cosmo_dlsym(handle, "cosmoaudio_poll");
|
||||
}
|
||||
|
||||
static void cosmoaudio_setup(void) {
|
||||
BLOCK_CANCELATION;
|
||||
cosmoaudio_setup_impl();
|
||||
ALLOW_CANCELATION;
|
||||
}
|
||||
|
||||
static void cosmoaudio_init(void) {
|
||||
pthread_once(&g_audio.once, cosmoaudio_setup);
|
||||
}
|
||||
|
@ -249,10 +257,13 @@ COSMOAUDIO_ABI int cosmoaudio_open(
|
|||
char sbuf[32];
|
||||
char dbuf[256];
|
||||
cosmoaudio_init();
|
||||
if (g_audio.open)
|
||||
if (g_audio.open) {
|
||||
BLOCK_SIGNALS;
|
||||
status = g_audio.open(out_ca, options);
|
||||
else
|
||||
ALLOW_SIGNALS;
|
||||
} else {
|
||||
status = COSMOAUDIO_ELINK;
|
||||
}
|
||||
STRACE("cosmoaudio_open([%p], %s) → %s",
|
||||
out_ca ? *out_ca : (struct CosmoAudio *)-1,
|
||||
cosmoaudio_describe_open_options(dbuf, sizeof(dbuf), options),
|
||||
|
@ -263,10 +274,13 @@ COSMOAUDIO_ABI int cosmoaudio_open(
|
|||
COSMOAUDIO_ABI int cosmoaudio_close(struct CosmoAudio *ca) {
|
||||
int status;
|
||||
char sbuf[32];
|
||||
if (g_audio.close)
|
||||
if (g_audio.close) {
|
||||
BLOCK_SIGNALS;
|
||||
status = g_audio.close(ca);
|
||||
else
|
||||
ALLOW_SIGNALS;
|
||||
} else {
|
||||
status = COSMOAUDIO_ELINK;
|
||||
}
|
||||
STRACE("cosmoaudio_close(%p) → %s", ca,
|
||||
cosmoaudio_describe_status(sbuf, sizeof(sbuf), status));
|
||||
return status;
|
||||
|
@ -276,10 +290,13 @@ COSMOAUDIO_ABI int cosmoaudio_write(struct CosmoAudio *ca, const float *data,
|
|||
int frames) {
|
||||
int status;
|
||||
char sbuf[32];
|
||||
if (g_audio.write)
|
||||
if (g_audio.write) {
|
||||
BLOCK_SIGNALS;
|
||||
status = g_audio.write(ca, data, frames);
|
||||
else
|
||||
ALLOW_SIGNALS;
|
||||
} else {
|
||||
status = COSMOAUDIO_ELINK;
|
||||
}
|
||||
if (frames <= 0 || frames >= 160)
|
||||
DATATRACE("cosmoaudio_write(%p, %p, %d) → %s", ca, data, frames,
|
||||
cosmoaudio_describe_status(sbuf, sizeof(sbuf), status));
|
||||
|
@ -290,10 +307,13 @@ COSMOAUDIO_ABI int cosmoaudio_read(struct CosmoAudio *ca, float *data,
|
|||
int frames) {
|
||||
int status;
|
||||
char sbuf[32];
|
||||
if (g_audio.read)
|
||||
if (g_audio.read) {
|
||||
BLOCK_SIGNALS;
|
||||
status = g_audio.read(ca, data, frames);
|
||||
else
|
||||
ALLOW_SIGNALS;
|
||||
} else {
|
||||
status = COSMOAUDIO_ELINK;
|
||||
}
|
||||
if (frames <= 0 || frames >= 160)
|
||||
DATATRACE("cosmoaudio_read(%p, %p, %d) → %s", ca, data, frames,
|
||||
cosmoaudio_describe_status(sbuf, sizeof(sbuf), status));
|
||||
|
@ -303,10 +323,13 @@ COSMOAUDIO_ABI int cosmoaudio_read(struct CosmoAudio *ca, float *data,
|
|||
COSMOAUDIO_ABI int cosmoaudio_flush(struct CosmoAudio *ca) {
|
||||
int status;
|
||||
char sbuf[32];
|
||||
if (g_audio.flush)
|
||||
if (g_audio.flush) {
|
||||
BLOCK_SIGNALS;
|
||||
status = g_audio.flush(ca);
|
||||
else
|
||||
ALLOW_SIGNALS;
|
||||
} else {
|
||||
status = COSMOAUDIO_ELINK;
|
||||
}
|
||||
DATATRACE("cosmoaudio_flush(%p) → %s", ca,
|
||||
cosmoaudio_describe_status(sbuf, sizeof(sbuf), status));
|
||||
return status;
|
||||
|
@ -318,10 +341,13 @@ COSMOAUDIO_ABI int cosmoaudio_poll(struct CosmoAudio *ca,
|
|||
int status;
|
||||
char sbuf[32];
|
||||
char fbuf[2][20];
|
||||
if (g_audio.poll)
|
||||
if (g_audio.poll) {
|
||||
BLOCK_SIGNALS;
|
||||
status = g_audio.poll(ca, in_out_readFrames, in_out_writeFrames);
|
||||
else
|
||||
ALLOW_SIGNALS;
|
||||
} else {
|
||||
status = COSMOAUDIO_ELINK;
|
||||
}
|
||||
DATATRACE("cosmoaudio_poll(%p, %s, %s) → %s", ca,
|
||||
cosmoaudio_describe_poll_frames(fbuf[0], sizeof(fbuf[0]),
|
||||
in_out_readFrames),
|
||||
|
|
|
@ -19,25 +19,19 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MA_STATIC
|
||||
#define MA_DEBUG_OUTPUT
|
||||
#define MA_DR_MP3_NO_STDIO
|
||||
#define MA_NO_DECODING
|
||||
#define MA_NO_ENCODING
|
||||
#define MA_NO_ENGINE
|
||||
#define MA_NO_GENERATION
|
||||
#define MA_NO_NODE_GRAPH
|
||||
#define MA_NO_RESOURCE_MANAGER
|
||||
#ifdef NDEBUG
|
||||
#define MA_DR_MP3_NO_STDIO
|
||||
#endif
|
||||
#define MA_STATIC
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define LOG(...) fprintf(stderr, __VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...) (void)0
|
||||
#endif
|
||||
|
||||
struct CosmoAudio {
|
||||
enum CosmoAudioDeviceType deviceType;
|
||||
ma_uint32 outputBufferFrames;
|
||||
|
@ -45,14 +39,16 @@ struct CosmoAudio {
|
|||
int sampleRate;
|
||||
int channels;
|
||||
int isLeft;
|
||||
ma_context context;
|
||||
ma_device device;
|
||||
ma_pcm_rb output;
|
||||
ma_pcm_rb input;
|
||||
ma_event event;
|
||||
ma_log log;
|
||||
};
|
||||
|
||||
static int read_ring_buffer(ma_pcm_rb* rb, float* pOutput, ma_uint32 frameCount,
|
||||
ma_uint32 channels) {
|
||||
static int read_ring_buffer(ma_log* log, ma_pcm_rb* rb, float* pOutput,
|
||||
ma_uint32 frameCount, ma_uint32 channels) {
|
||||
ma_result result;
|
||||
ma_uint32 framesRead;
|
||||
ma_uint32 framesToRead;
|
||||
|
@ -61,7 +57,9 @@ static int read_ring_buffer(ma_pcm_rb* rb, float* pOutput, ma_uint32 frameCount,
|
|||
void* pMappedBuffer;
|
||||
result = ma_pcm_rb_acquire_read(rb, &framesToRead, &pMappedBuffer);
|
||||
if (result != MA_SUCCESS) {
|
||||
LOG("ma_pcm_rb_acquire_read failed: %s\n", ma_result_description(result));
|
||||
ma_log_postf(log, MA_LOG_LEVEL_WARNING,
|
||||
"ma_pcm_rb_acquire_read failed: %s\n",
|
||||
ma_result_description(result));
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
if (!framesToRead)
|
||||
|
@ -74,14 +72,16 @@ static int read_ring_buffer(ma_pcm_rb* rb, float* pOutput, ma_uint32 frameCount,
|
|||
framesRead += framesToRead;
|
||||
break;
|
||||
}
|
||||
LOG("ma_pcm_rb_commit_read failed: %s\n", ma_result_description(result));
|
||||
ma_log_postf(log, MA_LOG_LEVEL_WARNING,
|
||||
"ma_pcm_rb_commit_read failed: %s\n",
|
||||
ma_result_description(result));
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
}
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
static int write_ring_buffer(ma_pcm_rb* rb, const float* pInput,
|
||||
static int write_ring_buffer(ma_log* log, ma_pcm_rb* rb, const float* pInput,
|
||||
ma_uint32 frameCount, ma_uint32 channels) {
|
||||
ma_result result;
|
||||
ma_uint32 framesWritten;
|
||||
|
@ -92,8 +92,9 @@ static int write_ring_buffer(ma_pcm_rb* rb, const float* pInput,
|
|||
void* pMappedBuffer;
|
||||
result = ma_pcm_rb_acquire_write(rb, &framesToWrite, &pMappedBuffer);
|
||||
if (result != MA_SUCCESS) {
|
||||
LOG("ma_pcm_rb_acquire_write failed: %s\n",
|
||||
ma_result_description(result));
|
||||
ma_log_postf(log, MA_LOG_LEVEL_WARNING,
|
||||
"ma_pcm_rb_acquire_write failed: %s\n",
|
||||
ma_result_description(result));
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
if (!framesToWrite)
|
||||
|
@ -106,7 +107,9 @@ static int write_ring_buffer(ma_pcm_rb* rb, const float* pInput,
|
|||
framesWritten += framesToWrite;
|
||||
break;
|
||||
}
|
||||
LOG("ma_pcm_rb_commit_write failed: %s\n", ma_result_description(result));
|
||||
ma_log_postf(log, MA_LOG_LEVEL_WARNING,
|
||||
"ma_pcm_rb_commit_write failed: %s\n",
|
||||
ma_result_description(result));
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -126,8 +129,8 @@ static void data_callback_f32(ma_device* pDevice, float* pOutput,
|
|||
// —Quoth miniaudio documentation § 16.1. Low Level API
|
||||
//
|
||||
if (ca->isLeft) {
|
||||
int framesCopied =
|
||||
read_ring_buffer(&ca->output, pOutput, frameCount, ca->channels);
|
||||
int framesCopied = read_ring_buffer(&ca->log, &ca->output, pOutput,
|
||||
frameCount, ca->channels);
|
||||
if (framesCopied < (int)frameCount)
|
||||
ca->isLeft = 0;
|
||||
} else {
|
||||
|
@ -140,13 +143,14 @@ static void data_callback_f32(ma_device* pDevice, float* pOutput,
|
|||
frameOffset = frameCount - availableFrames;
|
||||
frameCount = availableFrames;
|
||||
}
|
||||
read_ring_buffer(&ca->output, pOutput + frameOffset * ca->channels,
|
||||
frameCount, ca->channels);
|
||||
read_ring_buffer(&ca->log, &ca->output,
|
||||
pOutput + frameOffset * ca->channels, frameCount,
|
||||
ca->channels);
|
||||
ca->isLeft = 1;
|
||||
}
|
||||
}
|
||||
if (ca->deviceType & kCosmoAudioDeviceTypeCapture)
|
||||
write_ring_buffer(&ca->input, pInput, frameCount, ca->channels);
|
||||
write_ring_buffer(&ca->log, &ca->input, pInput, frameCount, ca->channels);
|
||||
ma_event_signal(&ca->event);
|
||||
}
|
||||
|
||||
|
@ -211,6 +215,25 @@ COSMOAUDIO_ABI int cosmoaudio_open( //
|
|||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
|
||||
// Create audio log.
|
||||
if (ma_log_init(NULL, &ca->log) != MA_SUCCESS) {
|
||||
ma_event_uninit(&ca->event);
|
||||
free(ca);
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
if (!options->debugLog)
|
||||
ca->log.callbackCount = 0;
|
||||
|
||||
// Create audio context.
|
||||
ma_context_config contextConfig = ma_context_config_init();
|
||||
contextConfig.pLog = &ca->log;
|
||||
if (ma_context_init(NULL, 0, &contextConfig, &ca->context) != MA_SUCCESS) {
|
||||
ma_event_uninit(&ca->event);
|
||||
ma_log_uninit(&ca->log);
|
||||
free(ca);
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
|
||||
// Initialize device.
|
||||
ma_result result;
|
||||
ma_device_config deviceConfig;
|
||||
|
@ -227,9 +250,11 @@ COSMOAUDIO_ABI int cosmoaudio_open( //
|
|||
}
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
deviceConfig.pUserData = ca;
|
||||
result = ma_device_init(NULL, &deviceConfig, &ca->device);
|
||||
result = ma_device_init(&ca->context, &deviceConfig, &ca->device);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_context_uninit(&ca->context);
|
||||
ma_event_uninit(&ca->event);
|
||||
ma_log_uninit(&ca->log);
|
||||
free(ca);
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
|
@ -248,7 +273,9 @@ COSMOAUDIO_ABI int cosmoaudio_open( //
|
|||
NULL, NULL, &ca->output);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_device_uninit(&ca->device);
|
||||
ma_context_uninit(&ca->context);
|
||||
ma_event_uninit(&ca->event);
|
||||
ma_log_uninit(&ca->log);
|
||||
free(ca);
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
|
@ -268,10 +295,12 @@ COSMOAUDIO_ABI int cosmoaudio_open( //
|
|||
result = ma_pcm_rb_init(ma_format_f32, ca->channels, ca->inputBufferFrames,
|
||||
NULL, NULL, &ca->input);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_device_uninit(&ca->device);
|
||||
if (ca->deviceType & kCosmoAudioDeviceTypePlayback)
|
||||
ma_pcm_rb_uninit(&ca->output);
|
||||
ma_device_uninit(&ca->device);
|
||||
ma_context_uninit(&ca->context);
|
||||
ma_event_uninit(&ca->event);
|
||||
ma_log_uninit(&ca->log);
|
||||
free(ca);
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
|
@ -280,12 +309,14 @@ COSMOAUDIO_ABI int cosmoaudio_open( //
|
|||
|
||||
// Start audio playback.
|
||||
if (ma_device_start(&ca->device) != MA_SUCCESS) {
|
||||
ma_device_uninit(&ca->device);
|
||||
if (ca->deviceType & kCosmoAudioDeviceTypePlayback)
|
||||
ma_pcm_rb_uninit(&ca->output);
|
||||
if (ca->deviceType & kCosmoAudioDeviceTypeCapture)
|
||||
ma_pcm_rb_uninit(&ca->input);
|
||||
ma_device_uninit(&ca->device);
|
||||
ma_context_uninit(&ca->context);
|
||||
ma_event_uninit(&ca->event);
|
||||
ma_log_uninit(&ca->log);
|
||||
free(ca);
|
||||
return COSMOAUDIO_ERROR;
|
||||
}
|
||||
|
@ -311,12 +342,14 @@ COSMOAUDIO_ABI int cosmoaudio_open( //
|
|||
COSMOAUDIO_ABI int cosmoaudio_close(struct CosmoAudio* ca) {
|
||||
if (!ca)
|
||||
return COSMOAUDIO_EINVAL;
|
||||
ma_device_uninit(&ca->device); // do this first
|
||||
if (ca->deviceType & kCosmoAudioDeviceTypePlayback)
|
||||
ma_pcm_rb_uninit(&ca->output);
|
||||
if (ca->deviceType & kCosmoAudioDeviceTypeCapture)
|
||||
ma_pcm_rb_uninit(&ca->input);
|
||||
ma_device_uninit(&ca->device);
|
||||
ma_context_uninit(&ca->context);
|
||||
ma_event_uninit(&ca->event);
|
||||
ma_log_uninit(&ca->log);
|
||||
free(ca);
|
||||
return COSMOAUDIO_SUCCESS;
|
||||
}
|
||||
|
@ -330,6 +363,12 @@ COSMOAUDIO_ABI int cosmoaudio_close(struct CosmoAudio* ca) {
|
|||
* repeatedly called at a regular time interval. The caller should
|
||||
* have its own sleep loop for this purpose.
|
||||
*
|
||||
* This function never blocks. Programs that don't have their own timer
|
||||
* can use cosmoaudio_poll() to wait until audio may be written.
|
||||
*
|
||||
* For any given CosmoAudio object, it's assumed that only a single
|
||||
* thread will call this function.
|
||||
*
|
||||
* @param ca is CosmoAudio object returned earlier by cosmoaudio_open()
|
||||
* @param data is pointer to raw audio samples, expected to be in the range
|
||||
* -1.0 to 1.0, where channels are interleaved
|
||||
|
@ -351,17 +390,23 @@ COSMOAUDIO_ABI int cosmoaudio_write(struct CosmoAudio* ca, const float* data,
|
|||
return 0;
|
||||
if (!data)
|
||||
return COSMOAUDIO_EINVAL;
|
||||
return write_ring_buffer(&ca->output, data, frames, ca->channels);
|
||||
return write_ring_buffer(&ca->log, &ca->output, data, frames, ca->channels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads raw audio data from microphone.
|
||||
*
|
||||
* The data is read from a ring buffer in real-time, which is then
|
||||
* played back very soon on the audio device. This has tolerence for
|
||||
* a certain amount of buffering, but expects that this function is
|
||||
* repeatedly called at a regular time interval. The caller should
|
||||
* have its own sleep loop for this purpose.
|
||||
* played back on the audio device. This has tolerence for a certain
|
||||
* amount of buffering (based on the `bufferFrames` parameter passed to
|
||||
* cosmoaudio_open(), which by default assumes this function will be
|
||||
* called at at a regular time interval.
|
||||
*
|
||||
* This function never blocks. Programs that don't have their own timer
|
||||
* can use cosmoaudio_poll() to wait until audio may be read.
|
||||
*
|
||||
* For any given CosmoAudio object, it's assumed that only a single
|
||||
* thread will call this function.
|
||||
*
|
||||
* @param ca is CosmoAudio object returned earlier by cosmoaudio_open()
|
||||
* @param data is pointer to raw audio samples, expected to be in the range
|
||||
|
@ -382,11 +427,16 @@ COSMOAUDIO_ABI int cosmoaudio_read(struct CosmoAudio* ca, float* data,
|
|||
return 0;
|
||||
if (!data)
|
||||
return COSMOAUDIO_EINVAL;
|
||||
return read_ring_buffer(&ca->input, data, frames, ca->channels);
|
||||
return read_ring_buffer(&ca->log, &ca->input, data, frames, ca->channels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for read and/or write to become possible.
|
||||
* Waits until it's possible to read/write audio.
|
||||
*
|
||||
* This function is uninterruptible. All signals are masked throughout
|
||||
* the duration of time this function may block, including cancelation
|
||||
* signals, because this is not a cancelation point. Cosmopolitan Libc
|
||||
* applies this masking in its dlopen wrapper.
|
||||
*
|
||||
* @param ca is CosmoAudio object returned earlier by cosmoaudio_open()
|
||||
* @param in_out_readFrames if non-NULL specifies how many frames of
|
||||
|
@ -447,6 +497,11 @@ COSMOAUDIO_ABI int cosmoaudio_poll(struct CosmoAudio* ca,
|
|||
*
|
||||
* This function is only valid to call in playback or duplex mode.
|
||||
*
|
||||
* This function is uninterruptible. All signals are masked throughout
|
||||
* the duration of time this function may block, including cancelation
|
||||
* signals, because this is not a cancelation point. Cosmopolitan Libc
|
||||
* applies this masking in its dlopen wrapper.
|
||||
*
|
||||
* @param ca is CosmoAudio object returned earlier by cosmoaudio_open()
|
||||
* @return 0 on success, or negative error code on failure
|
||||
*/
|
||||
|
|
Binary file not shown.
|
@ -59,6 +59,9 @@ struct CosmoAudioOpenOptions {
|
|||
// sample for each channel. Set to 0 for default. If this is less than
|
||||
// the device period size times two, it'll be increased to that value.
|
||||
int bufferFrames;
|
||||
|
||||
// Enables debug logging if non-zero.
|
||||
int debugLog;
|
||||
};
|
||||
|
||||
COSMOAUDIO_API int cosmoaudio_version(void) COSMOAUDIO_ABI;
|
||||
|
|
|
@ -53,7 +53,7 @@ int main() {
|
|||
float t = (float)g++ / SAMPLING_RATE;
|
||||
float s = sinf(2 * M_PIf * WAVE_INTERVAL * t);
|
||||
for (int c = 0; c < CHANNELS; c++)
|
||||
buf[f * CHANNELS + c] = s;
|
||||
buf[f * CHANNELS + c] = s * .3f;
|
||||
}
|
||||
status = cosmoaudio_write(ca, buf, frames);
|
||||
if (status != frames) {
|
||||
|
|
|
@ -90,6 +90,13 @@ const char *cosmoaudio_describe_open_options(
|
|||
gotsome = true;
|
||||
}
|
||||
|
||||
if (options->debugLog) {
|
||||
if (gotsome)
|
||||
append(", ");
|
||||
append(".debugLog=%d", options->debugLog);
|
||||
gotsome = true;
|
||||
}
|
||||
|
||||
if (options->sizeofThis) {
|
||||
if (gotsome)
|
||||
append(", ");
|
||||
|
|
80
examples/a440.c
Normal file
80
examples/a440.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
#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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* @fileoverview plays pure A.440 tone on speakers for 1 second
|
||||
* @see https://en.wikipedia.org/wiki/A440_%28pitch_standard%29
|
||||
*/
|
||||
|
||||
#define SAMPLING_RATE 44100
|
||||
#define WAVE_INTERVAL 440
|
||||
#define CHANNELS 2
|
||||
#define LOUDNESS .3
|
||||
#define DEBUG_LOG 1
|
||||
|
||||
int main() {
|
||||
|
||||
struct CosmoAudioOpenOptions cao = {0};
|
||||
cao.sizeofThis = sizeof(struct CosmoAudioOpenOptions);
|
||||
cao.deviceType = kCosmoAudioDeviceTypePlayback;
|
||||
cao.sampleRate = SAMPLING_RATE;
|
||||
cao.debugLog = DEBUG_LOG;
|
||||
cao.channels = CHANNELS;
|
||||
|
||||
int status;
|
||||
struct CosmoAudio *ca;
|
||||
status = cosmoaudio_open(&ca, &cao);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to open audio: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
float buf[256 * CHANNELS];
|
||||
for (int g = 0; g < SAMPLING_RATE;) {
|
||||
int frames = 1;
|
||||
status = cosmoaudio_poll(ca, NULL, &frames);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to poll output: %d\n", status);
|
||||
return 2;
|
||||
}
|
||||
if (frames > 256)
|
||||
frames = 256;
|
||||
if (frames > SAMPLING_RATE - g)
|
||||
frames = SAMPLING_RATE - g;
|
||||
for (int f = 0; f < frames; ++f) {
|
||||
float t = (float)g++ / SAMPLING_RATE;
|
||||
float s = sinf(2 * M_PIf * WAVE_INTERVAL * t);
|
||||
for (int c = 0; c < CHANNELS; c++)
|
||||
buf[f * CHANNELS + c] = s * LOUDNESS;
|
||||
}
|
||||
status = cosmoaudio_write(ca, buf, frames);
|
||||
if (status != frames) {
|
||||
fprintf(stderr, "failed to write output: %d\n", status);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
status = cosmoaudio_flush(ca);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to flush output: %d\n", status);
|
||||
return 4;
|
||||
}
|
||||
|
||||
status = cosmoaudio_close(ca);
|
||||
if (status != COSMOAUDIO_SUCCESS) {
|
||||
fprintf(stderr, "failed to close audio: %d\n", status);
|
||||
return 5;
|
||||
}
|
||||
}
|
|
@ -14,16 +14,16 @@
|
|||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include "libc/assert.h"
|
||||
|
||||
// high performance high accuracy matrix multiplication in ansi c
|
||||
|
||||
#define MATH __target_clones("avx512f,fma")
|
||||
#define MATH __target_clones("avx512f,fma,avx")
|
||||
|
||||
namespace {
|
||||
namespace ansiBLAS {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include <unistd.h>
|
||||
|
||||
// clears teletypewriter display
|
||||
//
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include <cosmo.h>
|
||||
|
||||
/**
|
||||
* @fileoverview How to print backtraces and cpu state on crash.
|
||||
|
|
|
@ -7,18 +7,11 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/enum/timezoneid.h"
|
||||
#include "libc/nt/struct/timezoneinformation.h"
|
||||
#include "libc/nt/time.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/threads.h"
|
||||
#include "libc/time.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <threads.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* @fileoverview High performance ISO-8601 timestamp formatter.
|
||||
|
@ -27,6 +20,8 @@
|
|||
* Consider using something like this instead for your loggers.
|
||||
*/
|
||||
|
||||
#define ABS(X) ((X) >= 0 ? (X) : -(X))
|
||||
|
||||
char *GetTimestamp(void) {
|
||||
int x;
|
||||
struct timespec ts;
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dlopen/dlfcn.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include <cosmo.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @fileoverview cosmopolitan dynamic runtime linking demo
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @fileoverview prints environment variables
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
fprintf(stderr, "%s (%s)\n", argv[0], GetProgramExecutableName());
|
||||
for (char** p = environ; *p; ++p) {
|
||||
printf("%s\n", *p);
|
||||
}
|
||||
for (char** p = environ; *p; ++p)
|
||||
puts(*p);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include <sys/auxv.h>
|
||||
#include <sys/socket.h>
|
||||
#include <time.h>
|
||||
#include "libc/mem/leaks.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* @fileoverview greenbean lightweight threaded web server
|
||||
|
|
|
@ -36,14 +36,10 @@
|
|||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/time.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
// clang-format off
|
||||
|
||||
#define DICT "usr/share/dict/hangman"
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("hello world\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
write(1, "hello world\n", 12);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#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 "libc/time.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int64_t t = 0;
|
||||
localtime(&t);
|
||||
}
|
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);
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
#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 "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/xasprintf.h"
|
||||
|
||||
struct stat st;
|
||||
|
||||
const char *TypeToString(uint8_t type) {
|
||||
switch (type) {
|
||||
case DT_UNKNOWN:
|
||||
return "DT_UNKNOWN";
|
||||
case DT_FIFO:
|
||||
return "DT_FIFO";
|
||||
case DT_CHR:
|
||||
return "DT_CHR";
|
||||
case DT_DIR:
|
||||
return "DT_DIR";
|
||||
case DT_BLK:
|
||||
return "DT_BLK";
|
||||
case DT_REG:
|
||||
return "DT_REG";
|
||||
case DT_LNK:
|
||||
return "DT_LNK";
|
||||
case DT_SOCK:
|
||||
return "DT_SOCK";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void List(const char *path) {
|
||||
DIR *d;
|
||||
struct dirent *e;
|
||||
const char *vpath;
|
||||
if (strcmp(path, ".") == 0) {
|
||||
vpath = "";
|
||||
} else if (!endswith(path, "/")) {
|
||||
vpath = gc(xasprintf("%s/", path));
|
||||
} else {
|
||||
vpath = path;
|
||||
}
|
||||
if (stat(path, &st) != -1) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
CHECK((d = opendir(path)));
|
||||
while ((e = readdir(d))) {
|
||||
printf("0x%016x 0x%016x %-10s %s%s\n", e->d_ino, e->d_off,
|
||||
TypeToString(e->d_type), vpath, e->d_name);
|
||||
}
|
||||
closedir(d);
|
||||
} else {
|
||||
printf("%s\n", path);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "not found: %s\n", path);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
if (argc == 1) {
|
||||
List(".");
|
||||
} else {
|
||||
for (i = 1; i < argc; ++i) {
|
||||
List(argv[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -7,25 +7,16 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/linger.h"
|
||||
#include "libc/sock/struct/pollfd.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/shut.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/netdb.h"
|
||||
#include <cosmo.h>
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
* @fileoverview netcat clone
|
||||
|
@ -36,12 +27,14 @@
|
|||
* Here's an example usage:
|
||||
*
|
||||
* make -j8 o//examples/nc.com
|
||||
* printf 'GET /\r\nHost: justine.lol\r\n\r\n' | o//examples/nc.com
|
||||
* justine.lol 80
|
||||
* printf 'GET /\r\nHost: justine.lol\r\n\r\n' | o//examples/nc.com justine.lol 80
|
||||
*
|
||||
* Once upon time we called this command "telnet"
|
||||
* Once upon time we called this command basically "telnet"
|
||||
*/
|
||||
|
||||
#define ARRAYLEN(A) \
|
||||
((sizeof(A) / sizeof(*(A))) / ((unsigned)!(sizeof(A) % sizeof(*(A)))))
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
ssize_t rc;
|
||||
size_t i, got;
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
#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 <stdio.h>
|
||||
|
||||
#define PARSE_AND_PRINT(type, scan_fmt, print_fmt, str) \
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/str/str.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
volatile int g_sig;
|
||||
|
||||
|
@ -21,16 +21,13 @@ void OnSig(int sig) {
|
|||
int main(int argc, char *argv[]) {
|
||||
|
||||
// listen for all signals
|
||||
for (int sig = 1; sig <= NSIG; ++sig) {
|
||||
for (int sig = 1; sig <= NSIG; ++sig)
|
||||
signal(sig, OnSig);
|
||||
}
|
||||
|
||||
// wait for a signal
|
||||
char ibuf[12];
|
||||
FormatInt32(ibuf, getpid());
|
||||
tinyprint(2, "waiting for signal to be sent to ", ibuf, "\n", NULL);
|
||||
printf("waiting for signal to be sent to my pid %d\n", getpid());
|
||||
pause();
|
||||
|
||||
// report the signal
|
||||
tinyprint(1, "got ", strsignal(g_sig), "\n", NULL);
|
||||
printf("got %s\n", strsignal(g_sig));
|
||||
}
|
||||
|
|
|
@ -32,12 +32,9 @@
|
|||
* . Formatted as per Cosmopolitan's standards.
|
||||
*/
|
||||
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
enum { PICOL_OK, PICOL_ERR, PICOL_RETURN, PICOL_BREAK, PICOL_CONTINUE };
|
||||
enum { PT_ESC, PT_STR, PT_CMD, PT_VAR, PT_SEP, PT_EOL, PT_EOF };
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include <cosmo.h>
|
||||
|
||||
int main() {
|
||||
__printargs("");
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include "libc/ctype.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Roman Transliteration, e.g.
|
||||
|
|
|
@ -29,29 +29,20 @@
|
|||
│ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF │
|
||||
│ SUCH DAMAGE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/termios.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/bswap.h"
|
||||
#include "libc/log/bsd.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/paths.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/select.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/time.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <pty.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include <cosmo.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @fileoverview Prints sequence of numbers.
|
||||
|
|
|
@ -7,12 +7,9 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
/**
|
||||
* @fileoverview swapcontext() and makecontext() example
|
||||
|
@ -33,18 +30,16 @@ static ucontext_t uctx_func2;
|
|||
static void func1(void) {
|
||||
say("func1: started\n");
|
||||
say("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
|
||||
if (swapcontext(&uctx_func1, &uctx_func2) == -1) {
|
||||
if (swapcontext(&uctx_func1, &uctx_func2) == -1)
|
||||
handle_error("swapcontext");
|
||||
}
|
||||
say("func1: returning\n");
|
||||
}
|
||||
|
||||
static void func2(void) {
|
||||
say("func2: started\n");
|
||||
say("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
|
||||
if (swapcontext(&uctx_func2, &uctx_func1) == -1) {
|
||||
if (swapcontext(&uctx_func2, &uctx_func1) == -1)
|
||||
handle_error("swapcontext");
|
||||
}
|
||||
say("func2: returning\n");
|
||||
}
|
||||
|
||||
|
@ -52,17 +47,15 @@ int main(int argc, char *argv[]) {
|
|||
char func1_stack[8192];
|
||||
char func2_stack[8192];
|
||||
|
||||
if (getcontext(&uctx_func1) == -1) {
|
||||
if (getcontext(&uctx_func1) == -1)
|
||||
handle_error("getcontext");
|
||||
}
|
||||
uctx_func1.uc_stack.ss_sp = func1_stack;
|
||||
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
|
||||
uctx_func1.uc_link = &uctx_main;
|
||||
makecontext(&uctx_func1, func1, 0);
|
||||
|
||||
if (getcontext(&uctx_func2) == -1) {
|
||||
if (getcontext(&uctx_func2) == -1)
|
||||
handle_error("getcontext");
|
||||
}
|
||||
uctx_func2.uc_stack.ss_sp = func2_stack;
|
||||
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
|
||||
/* Successor context is f1(), unless argc > 1 */
|
||||
|
@ -70,9 +63,8 @@ int main(int argc, char *argv[]) {
|
|||
makecontext(&uctx_func2, func2, 0);
|
||||
|
||||
say("main: swapcontext(&uctx_main, &uctx_func2)\n");
|
||||
if (swapcontext(&uctx_main, &uctx_func2) == -1) {
|
||||
if (swapcontext(&uctx_main, &uctx_func2) == -1)
|
||||
handle_error("swapcontext");
|
||||
}
|
||||
|
||||
say("main: exiting\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
@ -7,17 +7,15 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/itimer.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/time.h"
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* @fileoverview interval timer tutorial
|
||||
*/
|
||||
|
||||
volatile bool gotalrm;
|
||||
|
||||
|
|
|
@ -7,24 +7,20 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/proc/posix_spawn.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include <spawn.h>
|
||||
#include <stdalign.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <time.h>
|
||||
|
||||
#define ITERATIONS 10
|
||||
|
||||
_Alignas(128) int a;
|
||||
_Alignas(128) int b;
|
||||
_Alignas(128) atomic_int lock;
|
||||
alignas(128) int a;
|
||||
alignas(128) int b;
|
||||
alignas(128) atomic_int lock;
|
||||
|
||||
static struct timespec SubtractTime(struct timespec a, struct timespec b) {
|
||||
a.tv_sec -= b.tv_sec;
|
||||
|
|
|
@ -7,19 +7,12 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/time.h"
|
||||
#include <assert.h>
|
||||
#include <cosmo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* @fileoverview File metadata viewer.
|
||||
|
@ -72,9 +65,15 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
|
|||
printf("\n%s:", pathname);
|
||||
if (numeric) {
|
||||
fd = atoi(pathname);
|
||||
CHECK_NE(-1, fstat(fd, st), "fd=%d", fd);
|
||||
if (fstat(fd, st)) {
|
||||
perror(pathname);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
CHECK_NE(-1, stat(pathname, st), "pathname=%s", pathname);
|
||||
if (stat(pathname, st)) {
|
||||
perror(pathname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf("\n"
|
||||
"%-32s%,ld\n"
|
||||
|
|
|
@ -7,18 +7,19 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/struct/statfs.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/nt/enum/statfs.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/st.h"
|
||||
#include <cosmo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
dontinline void ShowIt(const char *path) {
|
||||
void ShowIt(const char *path) {
|
||||
char ibuf[21];
|
||||
struct statfs sf = {0};
|
||||
CHECK_NE(-1, statfs(path, &sf));
|
||||
if (statfs(path, &sf)) {
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("filesystem %s\n", path);
|
||||
printf("f_type = %#x (%s)\n", sf.f_type, sf.f_fstypename);
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
#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 "libc/calls/calls.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/append.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Fast Growable Strings Tutorial
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char *b = 0;
|
||||
appendf(&b, "hello "); // guarantees nul terminator
|
||||
CHECK_EQ(6, strlen(b));
|
||||
CHECK_EQ(6, appendz(b).i);
|
||||
appendf(&b, " world\n");
|
||||
CHECK_EQ(13, strlen(b));
|
||||
CHECK_EQ(13, appendz(b).i);
|
||||
appendd(&b, "\0", 1); // supports binary
|
||||
CHECK_EQ(13, strlen(b));
|
||||
CHECK_EQ(14, appendz(b).i);
|
||||
appendf(&b, "%d arg%s\n", argc, argc == 1 ? "" : "s");
|
||||
appendf(&b, "%s\n", "have a nice day");
|
||||
write(1, b, appendz(b).i);
|
||||
free(b);
|
||||
return 0;
|
||||
}
|
|
@ -7,8 +7,8 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SYSCONF(NAME) printf("%-24s %,ld\n", #NAME, sysconf(NAME))
|
||||
|
||||
|
|
|
@ -7,19 +7,19 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/struct/sysinfo.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include <cosmo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int64_t x;
|
||||
char ibuf[21];
|
||||
struct sysinfo si;
|
||||
CHECK_NE(-1, sysinfo(&si));
|
||||
if (sysinfo(&si)) {
|
||||
perror("sysinfo");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%-16s", "uptime");
|
||||
x = si.uptime / (24 * 60 * 60);
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @fileoverview Cosmopolitan Command Interpreter Demo
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_
|
||||
#define COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_
|
||||
#include "libc/calls/struct/statfs.h"
|
||||
#include "libc/sysv/consts/st.h"
|
||||
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_ */
|
||||
|
|
Loading…
Reference in a new issue