fa_buffer_t fa_buffer_zip(fa_buffer_t buffer1, fa_buffer_t buffer2) { size_t sz = SIZE_MIN(fa_buffer_size(buffer1), fa_buffer_size(buffer2)); fa_buffer_t buffer = fa_buffer_create(sz*2); for (int i = 0; i < sz; ++i) { buffer->data[i*2+0] = buffer1->data[i]; buffer->data[i*2+1] = buffer2->data[i]; } return buffer; }
fa_string_t buffer_show(fa_ptr_t a) { buffer_t buffer = (buffer_t) a; bool more = fa_buffer_size(buffer) > print_max_size_k; size_t length = more ? print_max_size_k : fa_buffer_size(buffer); string_t str = string("<Buffer"); for (size_t i = 0; i < length; ++i) { str = string_dappend(str, string(" ")); str = string_dappend(str, format_integral( "%02x", fa_buffer_get(buffer, i))); } if (more) { str = string_dappend(str, string(" ")); str = string_dappend(str, string("...")); } str = string_dappend(str, string(">")); return str; }
fa_pair_t fa_buffer_unzip(fa_buffer_t buffer) { size_t sz = fa_buffer_size(buffer); fa_buffer_t buffer1 = fa_buffer_create(sz/2); fa_buffer_t buffer2 = fa_buffer_create(sz/2); for (int i = 0; i < (sz/2); ++i) { buffer1->data[i] = buffer->data[i*2+0]; } for (int i = 0; i < (sz/2); ++i) { buffer2->data[i] = buffer->data[i*2+1]; } return fa_pair_create(buffer1, buffer2); }
fa_buffer_t fa_buffer_resample_mono(double new_rate, fa_buffer_t buffer) { size_t old_size = fa_buffer_size(buffer); double old_rate = fa_peek_int32(fa_buffer_get_meta(buffer, fa_string("sample-rate"))); size_t new_size = ((double) old_size) * (new_rate / old_rate); fa_buffer_t buffer2 = fa_buffer_create(new_size); resample_raw(old_rate, new_rate, (double*) buffer->data, old_size / sizeof(double), (double*) buffer2->data, new_size / sizeof(double)); buffer2->destroy_function = buffer->destroy_function; buffer2->destroy_data = buffer->destroy_data; buffer2->meta = fa_copy(buffer->meta); fa_buffer_set_meta(buffer, fa_string("sample-rate"), fa_from_int32(new_rate)); return buffer2; }
// TODO only writes one channel etc ptr_t fa_buffer_write_audio(fa_string_t path, int channels, fa_buffer_t buffer) { assert(channels == 1 && "fa_buffer_write_audio: Can not write more than 1 channels"); const char *cpath = fa_string_to_utf8(path); double *ptr = fa_buffer_unsafe_address(buffer); size_t size = fa_buffer_size(buffer) / sizeof(double); SF_INFO info; info.samplerate = 44100; info.channels = 1; info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24; //SNDFILE *file = sf_open(cpath, SFM_WRITE, &info); // if (sf_error(file)) { // char err[100]; // snprintf(err, 100, "Could not write audio file '%s' (%s)", cpath, sf_strerror(file)); // return (pair_t) fa_error_create_simple( // error, string(err), string("Doremir.Buffer")); // } //sf_count_t written = sf_write_double(file, ptr, size); // if (written != size) { // return (pair_t) fa_error_create_simple(error, string("To few bytes written"), string("Doremir.Buffer")); // } // if (sf_close(file)) { // return (pair_t) fa_error_create_simple(error, string("Could not close"), string("Doremir.Buffer")); // } return NULL; // file = 0; // cpath = 0; // assert(false); }