1
0

template.c: support stdout output

This commit is contained in:
Intel A80486DX2-66 2024-06-03 00:49:16 +03:00
parent 35fe39b0e0
commit 0d65942d81
Signed by: 80486DX2-66
GPG Key ID: 83631EF27054609B

View File

@ -27,6 +27,7 @@ typedef long double bb_fp_return_t;
#endif #endif
#define OUTPUT_FILE `output_file` #define OUTPUT_FILE `output_file`
#define STDOUT_OUTPUT (OUTPUT_FILE == "-")
#define SAMPLE_RATE `sample_rate` #define SAMPLE_RATE `sample_rate`
#define ORIGINAL_SAMPLE_RATE `original_sample_rate` #define ORIGINAL_SAMPLE_RATE `original_sample_rate`
@ -86,6 +87,16 @@ typedef long double bb_fp_return_t;
#define STRINGIZE(x) #x #define STRINGIZE(x) #x
#define INT2STR(x) STRINGIZE(x) #define INT2STR(x) STRINGIZE(x)
#if STDOUT_OUTPUT
# define smart_printf(...) fprintf(stderr, __VA_ARGS__)
# define smart_puts(s) fprintf(stderr, s "\n")
# define smart_fflush fflush(stderr)
#else
# define smart_printf printf
# define smart_puts puts
# define smart_fflush fflush(stdout)
#endif
// macros // macros
#define ALLOCATE_MEMORY(nmemb) \ #define ALLOCATE_MEMORY(nmemb) \
SAMPLE_TYPE* buffer = malloc( \ SAMPLE_TYPE* buffer = malloc( \
@ -137,21 +148,22 @@ print_time(uintmax_t length) {
if (seconds > 0) if (seconds > 0)
if (seconds >= 3600) if (seconds >= 3600)
printf( smart_printf(
"%" PRIuMAX ":%02" PRIuMAX ":%02" PRIuMAX, "%" PRIuMAX ":%02" PRIuMAX ":%02" PRIuMAX,
seconds / 3600, seconds / 3600,
(seconds / 60) % 60, (seconds / 60) % 60,
seconds % 60); seconds % 60);
else if (seconds >= 60) else if (seconds >= 60)
printf("%" PRIuMAX ":%02" PRIuMAX, seconds / 60, seconds % 60); smart_printf("%" PRIuMAX ":%02" PRIuMAX, seconds / 60,
seconds % 60);
else else
printf("%" PRIuMAX " seconds", seconds); smart_printf("%" PRIuMAX " seconds", seconds);
if (seconds > 0 && samples > 0) if (seconds > 0 && samples > 0)
printf(" + "); smart_printf(" + ");
if (samples > 0) if (samples > 0)
printf("%" PRIuMAX " samples", samples); smart_printf("%" PRIuMAX " samples", samples);
} }
int int
@ -159,13 +171,10 @@ main(void)
{ {
// * log -> welcome // * log -> welcome
#if !SILENT_MODE #if !SILENT_MODE
puts(":: C bytebeat generator: runtime unit"); smart_puts(":: C bytebeat generator: runtime unit");
fflush(stdout); smart_fflush();
const uintmax_t seconds = LENGTH / SAMPLE_RATE, smart_printf(
samples = LENGTH % SAMPLE_RATE;
printf(
"\n" "\n"
"Sample rate: " INT2STR(SAMPLE_RATE) " Hz\n" "Sample rate: " INT2STR(SAMPLE_RATE) " Hz\n"
"Channels: " INT2STR(CHANNELS) "Channels: " INT2STR(CHANNELS)
@ -193,40 +202,42 @@ main(void)
print_time(RUNNING_LENGTH); print_time(RUNNING_LENGTH);
#if REPEAT_TIMES > 0 #if REPEAT_TIMES > 0
printf(", %llu times -> ", REPEAT_TIMES + 1); smart_printf(", %llu times -> ", REPEAT_TIMES + 1);
print_time(RUNNING_LENGTH * (REPEAT_TIMES + 1)); print_time(RUNNING_LENGTH * (REPEAT_TIMES + 1));
#endif #endif
#if INITIAL_TIME != 0 #if INITIAL_TIME != 0
printf("\nStart time: "); smart_printf("\nStart time: ");
print_time(INITIAL_TIME); print_time(INITIAL_TIME);
#endif #endif
#if VERBOSE_MODE || SEQUENTIAL_MODE #if VERBOSE_MODE || SEQUENTIAL_MODE
puts("\n"); smart_puts("\n");
#endif #endif
fflush(stdout); smart_fflush();
#endif #endif
// * write WAVE headers // * write WAVE headers
// 0. log // 0. log
#if !SILENT_MODE && VERBOSE_MODE #if VERBOSE_MODE
puts("Writing WAVE headers..."); smart_puts("Writing WAVE headers...");
#endif #endif
#if !STDOUT_OUTPUT
// 1. open file // 1. open file
FILE* output_file = fopen(OUTPUT_FILE, FILE* output_file = fopen(OUTPUT_FILE,
"wb" "wb"
#if REPEAT_TIMES > 0 && SEQUENTIAL_MODE # if REPEAT_TIMES > 0 && SEQUENTIAL_MODE
"+" "+"
#endif # endif
); );
if (output_file == NULL) { if (output_file == NULL) {
fflush(stdout); smart_fflush();
perror("fopen"); perror("fopen");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
#endif
// 2. prepare variables // 2. prepare variables
const uint32_t header_size = const uint32_t header_size =
@ -253,6 +264,7 @@ main(void)
block_align = (ACTUAL_BIT_DEPTH * CHANNELS) / 8, block_align = (ACTUAL_BIT_DEPTH * CHANNELS) / 8,
bit_depth = ACTUAL_BIT_DEPTH; bit_depth = ACTUAL_BIT_DEPTH;
#if !STDOUT_OUTPUT
// 3. write headers // 3. write headers
// <L = Little-endian or B = Big-endian> : <name> : <bytes of field> // <L = Little-endian or B = Big-endian> : <name> : <bytes of field>
fwrite ("RIFF", 1, 4, output_file); // B : ChunkID : 4 fwrite ("RIFF", 1, 4, output_file); // B : ChunkID : 4
@ -268,6 +280,7 @@ main(void)
fwrite_le(&bit_depth, 2, 1, output_file); // L : BitsPerSample : 2 fwrite_le(&bit_depth, 2, 1, output_file); // L : BitsPerSample : 2
fwrite ("data", 1, 4, output_file); // B : Subchunk2ID : 4 fwrite ("data", 1, 4, output_file); // B : Subchunk2ID : 4
fwrite_le(&buffer_size, 4, 1, output_file); // L : Subchunk2Size : 4 fwrite_le(&buffer_size, 4, 1, output_file); // L : Subchunk2Size : 4
#endif
// 4. write sample data // 4. write sample data
#if SEQUENTIAL_MODE #if SEQUENTIAL_MODE
@ -360,10 +373,10 @@ main(void)
] = sample_res; ] = sample_res;
// 6. log // 6. log
#if VERBOSE_MODE #if VERBOSE_MODE && !STDOUT_OUTPUT
if (time % FREQUENCY_OF_STATUS_REPORTING == 0 || if (time % FREQUENCY_OF_STATUS_REPORTING == 0 ||
time >= LOOP_END_MINUS_1 /* or if writing last sample */) { time >= LOOP_END_MINUS_1 /* or if writing last sample */) {
printf( smart_printf(
"%sremaining samples = %18" PRIuMAX " (%6.2Lf%% done)" "%sremaining samples = %18" PRIuMAX " (%6.2Lf%% done)"
#if SEQUENTIAL_MODE #if SEQUENTIAL_MODE
" (part %" PRIuMAX "/%" PRIuMAX ")" " (part %" PRIuMAX "/%" PRIuMAX ")"
@ -376,26 +389,26 @@ main(void)
, (uintmax_t) seq + 1, (uintmax_t) MAX , (uintmax_t) seq + 1, (uintmax_t) MAX
#endif #endif
); );
fflush(stdout); smart_fflush();
} }
#endif #endif
} }
#if !SILENT_MODE #if !SILENT_MODE
printf(_ANSI_CLEAR_STRING); smart_printf(_ANSI_CLEAR_STRING);
// 5. log // 5. log
#if !(SEQUENTIAL_MODE && VERBOSE_MODE) #if !(SEQUENTIAL_MODE && VERBOSE_MODE)
# if SEQUENTIAL_MODE # if SEQUENTIAL_MODE
if (seq == 0) if (seq == 0)
# endif # endif
puts( smart_puts(
# if !SEQUENTIAL_MODE # if !SEQUENTIAL_MODE
"\n" "\n"
# endif # endif
"Writing out file " OUTPUT_FILE "..."); "Writing out file " OUTPUT_FILE "...");
#endif #endif
fflush(stdout); smart_fflush();
#endif #endif
// * save the sample data into the file // * save the sample data into the file
@ -405,9 +418,20 @@ main(void)
#else #else
GEN_LENGTH, GEN_LENGTH,
#endif #endif
output_file); #if STDOUT_OUTPUT
stdout
#else
output_file
#endif
);
#if SEQUENTIAL_MODE #if SEQUENTIAL_MODE
fflush(output_file); fflush(
# if STDOUT_OUTPUT
stdout
# else
output_file
# endif
);
#endif #endif
#if SEQUENTIAL_MODE #if SEQUENTIAL_MODE
@ -415,6 +439,7 @@ main(void)
#endif #endif
#if REPEAT_TIMES > 0 #if REPEAT_TIMES > 0
# if !(STDOUT_OUTPUT && !SEQUENTIAL_MODE)
// * repeat as much as needed // * repeat as much as needed
# if !SILENT_MODE # if !SILENT_MODE
@ -426,7 +451,7 @@ main(void)
# endif # endif
for (size_t counter = 0; counter < REPEAT_TIMES; counter++) { for (size_t counter = 0; counter < REPEAT_TIMES; counter++) {
# if SEQUENTIAL_MODE # if SEQUENTIAL_MODE
off_t position_read = header_size; off_t position_read = header_size;
calc_block_size = BLOCK_SIZE; calc_block_size = BLOCK_SIZE;
@ -447,17 +472,22 @@ main(void)
position_read += calc_block_size; position_read += calc_block_size;
} }
# else # else
fwrite_le(buffer, sizeof(SAMPLE_TYPE), GEN_LENGTH, output_file); fwrite_le(buffer, sizeof(SAMPLE_TYPE), GEN_LENGTH, output_file);
# endif # endif
} }
# else
fprintf(stderr, "Repeating is not supported in STDOUT, sequential mode\n");
# endif
#endif #endif
// * free allocated heap // * free allocated heap
free(buffer); free(buffer);
#if !STDOUT_OUTPUT
// 6. close file // 6. close file
fclose(output_file); fclose(output_file);
#endif
// * end of program // * end of program
#if !SILENT_MODE #if !SILENT_MODE