template.c: add sequential mode and set as default
This commit is contained in:
parent
67ab00c084
commit
d1906f0dc1
@ -124,6 +124,11 @@ if __name__ == "__main__":
|
|||||||
"default = +0 samples")
|
"default = +0 samples")
|
||||||
parser.add_argument("-a", "--no-return", default=False, action="store_true",
|
parser.add_argument("-a", "--no-return", default=False, action="store_true",
|
||||||
help="do not insert return statement before the code")
|
help="do not insert return statement before the code")
|
||||||
|
parser.add_argument("-u", "--mode", default="sequential", type=str,
|
||||||
|
help="mode of writing: `sequential` or `instant` (the latter is not "
|
||||||
|
"recommended, since the whole result would be stored in RAM)")
|
||||||
|
parser.add_argument("-n", "--block-size", default=65536, type=int,
|
||||||
|
help="sequential mode only: block size of each sequence, bytes")
|
||||||
parser.add_argument("-q", "--silent", default=False, action="store_true",
|
parser.add_argument("-q", "--silent", default=False, action="store_true",
|
||||||
help="do not output anything during generation")
|
help="do not output anything during generation")
|
||||||
parser.add_argument("-v", "--verbose", default=False, action="store_true",
|
parser.add_argument("-v", "--verbose", default=False, action="store_true",
|
||||||
@ -186,6 +191,9 @@ if __name__ == "__main__":
|
|||||||
print("CLI: Count of samples should be greater than zero.")
|
print("CLI: Count of samples should be greater than zero.")
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
if args.mode != "sequential" and args.mode != "instant":
|
||||||
|
print("Invalid mode '%s'" % args.mode)
|
||||||
|
|
||||||
rewrite_file(PATHS["substitute"], substitute_vars({
|
rewrite_file(PATHS["substitute"], substitute_vars({
|
||||||
"bytebeat_contents": bytebeat_contents,
|
"bytebeat_contents": bytebeat_contents,
|
||||||
"output_file": C_str_repr(args.output),
|
"output_file": C_str_repr(args.output),
|
||||||
@ -199,6 +207,8 @@ if __name__ == "__main__":
|
|||||||
"fp_return_type": args.floating_point,
|
"fp_return_type": args.floating_point,
|
||||||
"channels": args.channels,
|
"channels": args.channels,
|
||||||
"length": samples,
|
"length": samples,
|
||||||
|
"sequential_mode": args.mode == "sequential",
|
||||||
|
"block_size": args.block_size,
|
||||||
"silent_mode": args.silent,
|
"silent_mode": args.silent,
|
||||||
"verbose_mode": args.verbose and not args.silent,
|
"verbose_mode": args.verbose and not args.silent,
|
||||||
"fwrite_le": "../" + PATHS["fwrite_le_header"]
|
"fwrite_le": "../" + PATHS["fwrite_le_header"]
|
||||||
|
214
src/template.c
214
src/template.c
@ -41,6 +41,9 @@ const char* ANSI_CLEAR = __ANSI_CLEAR_STRING;
|
|||||||
#define PRODUCT (LENGTH * CHANNELS)
|
#define PRODUCT (LENGTH * CHANNELS)
|
||||||
#define FREQUENCY_OF_STATUS_REPORTING 5000
|
#define FREQUENCY_OF_STATUS_REPORTING 5000
|
||||||
|
|
||||||
|
#define SEQUENTIAL_MODE `sequential_mode`
|
||||||
|
#define BLOCK_SIZE_BYTES `block_size`
|
||||||
|
|
||||||
#define FP_RETURN_TYPE `fp_return_type`
|
#define FP_RETURN_TYPE `fp_return_type`
|
||||||
#define PRECALCULATED_RATIO `precalculated_ratio`
|
#define PRECALCULATED_RATIO `precalculated_ratio`
|
||||||
|
|
||||||
@ -71,8 +74,12 @@ bytebeat(long double w)
|
|||||||
{
|
{
|
||||||
#if PRECALCULATED_RATIO
|
#if PRECALCULATED_RATIO
|
||||||
`final_sample_rate_code`
|
`final_sample_rate_code`
|
||||||
#else
|
#elif ORIGINAL_SAMPLE_RATE != SAMPLE_RATE
|
||||||
|
# if SAMPLE_RATE > ORIGINAL_SAMPLE_RATE
|
||||||
w /= ((long double) SAMPLE_RATE) / ((long double) ORIGINAL_SAMPLE_RATE);
|
w /= ((long double) SAMPLE_RATE) / ((long double) ORIGINAL_SAMPLE_RATE);
|
||||||
|
# else
|
||||||
|
w *= ((long double) ORIGINAL_SAMPLE_RATE / ((long double) SAMPLE_RATE));
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
uintmax_t t = (uintmax_t) w;
|
uintmax_t t = (uintmax_t) w;
|
||||||
`bytebeat_contents`;
|
`bytebeat_contents`;
|
||||||
@ -122,7 +129,7 @@ main(void)
|
|||||||
printf("%" PRIuMAX " samples", samples);
|
printf("%" PRIuMAX " samples", samples);
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
#if VERBOSE_MODE
|
#if VERBOSE_MODE || SEQUENTIAL_MODE
|
||||||
"\n"
|
"\n"
|
||||||
#endif
|
#endif
|
||||||
"\n"
|
"\n"
|
||||||
@ -132,6 +139,11 @@ main(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * write WAVE headers
|
// * write WAVE headers
|
||||||
|
// 0. log
|
||||||
|
#if SEQUENTIAL_MODE
|
||||||
|
printf("Writing WAVE headers...\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
// 1. open file
|
// 1. open file
|
||||||
FILE* output_file = fopen(OUTPUT_FILE, "wb");
|
FILE* output_file = fopen(OUTPUT_FILE, "wb");
|
||||||
if (output_file == NULL) {
|
if (output_file == NULL) {
|
||||||
@ -146,10 +158,10 @@ main(void)
|
|||||||
5 * 4 /* 4 uint32_t values */ +
|
5 * 4 /* 4 uint32_t values */ +
|
||||||
4 * 2 /* 5 uint16_t values */ +
|
4 * 2 /* 5 uint16_t values */ +
|
||||||
PRODUCT /* sample data */,
|
PRODUCT /* sample data */,
|
||||||
fmt_data_length = 16 /*
|
fmt_data_length = 16 /* <--
|
||||||
* length of format data before this value
|
* length of format data before this value
|
||||||
* in the file format structure
|
* in the file format structure
|
||||||
*/,
|
*/,
|
||||||
sample_rate = SAMPLE_RATE,
|
sample_rate = SAMPLE_RATE,
|
||||||
byte_rate = (SAMPLE_RATE * BIT_DEPTH * CHANNELS) / 8;
|
byte_rate = (SAMPLE_RATE * BIT_DEPTH * CHANNELS) / 8;
|
||||||
uint16_t fmt_type = 1, // format type is PCM
|
uint16_t fmt_type = 1, // format type is PCM
|
||||||
@ -174,93 +186,155 @@ main(void)
|
|||||||
fwrite_le(&buffer_size, 4, 1, output_file); // L : Subchunk2Size : 4
|
fwrite_le(&buffer_size, 4, 1, output_file); // L : Subchunk2Size : 4
|
||||||
|
|
||||||
// 4. write sample data
|
// 4. write sample data
|
||||||
// * allocate heap for sample data
|
#if SEQUENTIAL_MODE
|
||||||
SAMPLE_TYPE* buffer = calloc(PRODUCT, sizeof(SAMPLE_TYPE));
|
const size_t BLOCK_SIZE = BLOCK_SIZE_BYTES / (sizeof(SAMPLE_TYPE) /
|
||||||
|
sizeof(uint8_t));
|
||||||
if (buffer == NULL) {
|
if (BLOCK_SIZE < 1) {
|
||||||
perror("calloc");
|
printf("The block size %" PRIuMAX " is too small, should be at least "
|
||||||
return 1;
|
"%" PRIuMAX " bytes\n", (uintmax_t) BLOCK_SIZE_BYTES,
|
||||||
|
(uintmax_t) (sizeof(SAMPLE_TYPE) / sizeof(uint8_t)));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
const size_t MAX = (PRODUCT + (BLOCK_SIZE - 1)) / BLOCK_SIZE;
|
||||||
|
|
||||||
// * bytebeat generating loop
|
size_t w = 0;
|
||||||
const uintmax_t product_minus_1 = PRODUCT - 1,
|
for (size_t seq = 0; seq < MAX; seq++) {
|
||||||
bit_depth_limiter = BIT_DEPTH_LIMITER
|
|
||||||
#if FP_RETURN_TYPE
|
|
||||||
+ 1
|
|
||||||
#endif
|
|
||||||
#if BIT_DEPTH < 8
|
|
||||||
,
|
|
||||||
bit_depth_stretch = ((long double) BIT_DEPTH) / 8.L
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
for (size_t w = 0; w < PRODUCT; w++) {
|
|
||||||
// 1. generate audio data
|
|
||||||
#if FP_RETURN_TYPE
|
|
||||||
long double bytebeat_res = floor(bytebeat((long double) floor(w)));
|
|
||||||
#elif IS_SIGNED
|
|
||||||
intmax_t bytebeat_res = (intmax_t) bytebeat(floor((long double) w));
|
|
||||||
#else
|
#else
|
||||||
uintmax_t bytebeat_res = (uintmax_t) bytebeat(floor((long double) w));
|
do {
|
||||||
#endif
|
#endif
|
||||||
|
size_t calc_block_size = BLOCK_SIZE;
|
||||||
|
if ((w + BLOCK_SIZE) >= PRODUCT)
|
||||||
|
calc_block_size = PRODUCT - w;
|
||||||
|
|
||||||
// 2. if signed, then wrap up into unsigned
|
// * allocate heap for sample data
|
||||||
#if IS_SIGNED
|
SAMPLE_TYPE* buffer = calloc(
|
||||||
bytebeat_res = signed_to_unsigned(bytebeat_res);
|
#if SEQUENTIAL_MODE
|
||||||
#endif
|
calc_block_size,
|
||||||
|
|
||||||
// 3. convert audio data to sample
|
|
||||||
SAMPLE_TYPE sample_res = (SAMPLE_TYPE)
|
|
||||||
#if FP_RETURN_TYPE
|
|
||||||
fmodl(bytebeat_res, bit_depth_limiter);
|
|
||||||
#else
|
#else
|
||||||
((uintmax_t) bytebeat_res & bit_depth_limiter);
|
PRODUCT,
|
||||||
#endif
|
#endif
|
||||||
|
sizeof(SAMPLE_TYPE));
|
||||||
|
|
||||||
// 4. if bit depth is less than 8, stretch it
|
if (buffer == NULL) {
|
||||||
#if BIT_DEPTH < 8
|
perror("calloc");
|
||||||
sample_res = (SAMPLE_TYPE)
|
return 1;
|
||||||
((long double) sample_res * bit_depth_stretch);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 5. save sample into buffer
|
|
||||||
buffer[w] = sample_res;
|
|
||||||
|
|
||||||
// 6. log
|
|
||||||
#if VERBOSE_MODE
|
|
||||||
if (w % FREQUENCY_OF_STATUS_REPORTING == 0 ||
|
|
||||||
w >= product_minus_1 /* or if writing last sample */) {
|
|
||||||
printf(
|
|
||||||
"%sremaining samples = %18" PRIuMAX " (%.2Lf%% done)",
|
|
||||||
ANSI_CLEAR,
|
|
||||||
product_minus_1 - w,
|
|
||||||
((long double) w * 100) / (long double) PRODUCT);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * bytebeat generating loop
|
||||||
|
const uintmax_t product_minus_1 = PRODUCT - 1,
|
||||||
|
bit_depth_limiter = BIT_DEPTH_LIMITER
|
||||||
|
#if FP_RETURN_TYPE
|
||||||
|
+ 1
|
||||||
#endif
|
#endif
|
||||||
}
|
#if BIT_DEPTH < 8
|
||||||
|
,
|
||||||
|
bit_depth_stretch = ((long double) BIT_DEPTH) / 8.L
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
#if SEQUENTIAL_MODE
|
||||||
|
size_t idx = 0;
|
||||||
|
for (; idx < BLOCK_SIZE && w < PRODUCT; idx++, w++) {
|
||||||
|
#else
|
||||||
|
for (size_t w = 0; w < PRODUCT; w++) {
|
||||||
|
#endif
|
||||||
|
// 1. generate audio data
|
||||||
|
#if FP_RETURN_TYPE
|
||||||
|
long double bytebeat_res = floor(bytebeat((long double) floor(w)));
|
||||||
|
#elif IS_SIGNED
|
||||||
|
intmax_t bytebeat_res = (intmax_t) bytebeat(floor((long double) w));
|
||||||
|
#else
|
||||||
|
uintmax_t bytebeat_res = (uintmax_t) bytebeat(floor((long double) w));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 2. if signed, then wrap up into unsigned
|
||||||
|
#if IS_SIGNED
|
||||||
|
bytebeat_res = signed_to_unsigned(bytebeat_res);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 3. convert audio data to sample
|
||||||
|
SAMPLE_TYPE sample_res = (SAMPLE_TYPE)
|
||||||
|
#if FP_RETURN_TYPE
|
||||||
|
fmodl(bytebeat_res, bit_depth_limiter);
|
||||||
|
#else
|
||||||
|
((uintmax_t) bytebeat_res & bit_depth_limiter);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 4. if bit depth is less than 8, stretch it
|
||||||
|
#if BIT_DEPTH < 8
|
||||||
|
sample_res = (SAMPLE_TYPE)
|
||||||
|
((long double) sample_res * bit_depth_stretch);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 5. save sample into buffer
|
||||||
|
#if SEQUENTIAL_MODE
|
||||||
|
buffer[idx] = sample_res;
|
||||||
|
#else
|
||||||
|
buffer[w] = sample_res;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 6. log
|
||||||
|
#if VERBOSE_MODE
|
||||||
|
if (w % FREQUENCY_OF_STATUS_REPORTING == 0 ||
|
||||||
|
w >= product_minus_1 /* or if writing last sample */) {
|
||||||
|
printf(
|
||||||
|
"%sremaining samples = %18" PRIuMAX " (%.2Lf%% done)",
|
||||||
|
ANSI_CLEAR,
|
||||||
|
product_minus_1 - w,
|
||||||
|
((long double) w * 100) / (long double) PRODUCT);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if !SILENT_MODE
|
#if !SILENT_MODE
|
||||||
printf("%s", ANSI_CLEAR);
|
printf("%s", ANSI_CLEAR);
|
||||||
|
|
||||||
// 5. log
|
// 5. log
|
||||||
printf("\nWriting out file " OUTPUT_FILE "...\n");
|
#if SEQUENTIAL_MODE
|
||||||
fflush(stdout);
|
printf("Writing out file " OUTPUT_FILE " (part %" PRIuMAX "/%"
|
||||||
|
PRIuMAX ", %.2Lf%%)...\n", (uintmax_t) seq + 1,
|
||||||
|
(uintmax_t) MAX,
|
||||||
|
((long double) seq * 100.L) / ((long double) MAX));
|
||||||
|
#else
|
||||||
|
printf("\nWriting out file " OUTPUT_FILE "...\n");
|
||||||
|
#endif
|
||||||
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * save the sample data into the file
|
// * save the sample data into the file
|
||||||
fwrite_le(buffer, sizeof(SAMPLE_TYPE), buffer_size, output_file);
|
fwrite_le(buffer, sizeof(SAMPLE_TYPE),
|
||||||
|
#if SEQUENTIAL_MODE
|
||||||
|
calc_block_size,
|
||||||
|
#else
|
||||||
|
PRODUCT,
|
||||||
|
#endif
|
||||||
|
output_file);
|
||||||
|
#if SEQUENTIAL_MODE
|
||||||
|
fflush(output_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SEQUENTIAL_MODE
|
||||||
|
// * free allocated heap
|
||||||
|
free(buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if !SEQUENTIAL_MODE
|
||||||
|
while (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 6. close file
|
// 6. close file
|
||||||
fclose(output_file);
|
fclose(output_file);
|
||||||
|
|
||||||
|
#if !SEQUENTIAL_MODE
|
||||||
|
// * free allocated heap
|
||||||
|
free(buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
// * end of program
|
// * end of program
|
||||||
#if !SILENT_MODE
|
#if !SILENT_MODE
|
||||||
printf("Done!\n");
|
printf("Done!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * free allocated heap
|
|
||||||
free(buffer);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user