1 /* 2 * Copyright (C) 2019-2020 Alexandros Theodotou <alex at zrythm dot org> 3 * 4 * This file is part of Zrythm 5 * 6 * Zrythm is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Zrythm is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * \file 22 * 23 * Time and pitch stretching API. 24 */ 25 26 #ifndef __AUDIO_STRETCHER_H__ 27 #define __AUDIO_STRETCHER_H__ 28 29 #include <stdbool.h> 30 #include <stddef.h> 31 #include <sys/types.h> 32 33 #include "utils/types.h" 34 35 #include <rubberband/rubberband-c.h> 36 37 /** 38 * @addtogroup audio 39 * 40 * @{ 41 */ 42 43 typedef enum StretcherBackend 44 { 45 /** Lib rubberband. */ 46 STRETCHER_BACKEND_RUBBERBAND, 47 48 /** Paulstretch. */ 49 STRETCHER_BACKEND_PAULSTRETCH, 50 51 /** SBSMS - Subband Sinusoidal Modeling 52 * Synthesis. */ 53 STRETCHER_BACKEND_SBSMS, 54 } StretcherBackend; 55 56 /** 57 * Stretcher interface. 58 */ 59 typedef struct Stretcher 60 { 61 StretcherBackend backend; 62 63 /** For rubberband API. */ 64 RubberBandState rubberband_state; 65 66 unsigned int samplerate; 67 unsigned int channels; 68 69 bool is_realtime; 70 71 /** 72 * Size of the block to process in each 73 * iteration. 74 * 75 * Somewhere around 6k should be fine. 76 */ 77 unsigned int block_size; 78 } Stretcher; 79 80 /** 81 * Create a new Stretcher using the rubberband 82 * backend. 83 * 84 * @param samplerate The new samplerate. 85 * @param time_ratio The ratio to multiply time by 86 * (eg if the BPM is doubled, this will be 0.5). 87 * @param pitch_ratio The ratio to pitch by. This 88 * will normally be 1.0 when time-stretching). 89 * @param realtime Whether to perform realtime 90 * stretching (lower quality but fast enough to 91 * be used real-time). 92 */ 93 Stretcher * 94 stretcher_new_rubberband ( 95 unsigned int samplerate, 96 unsigned int channels, 97 double time_ratio, 98 double pitch_ratio, 99 bool realtime); 100 101 /** 102 * Perform stretching. 103 * 104 * @param in_samples_l The left samples. 105 * @param in_samples_r The right channel samples. If 106 * this is NULL, the audio is assumed to be mono. 107 * @param in_samples_size The number of input samples 108 * per channel. 109 * 110 * @return The number of output samples generated per 111 * channel. 112 */ 113 ssize_t 114 stretcher_stretch ( 115 Stretcher * self, 116 float * in_samples_l, 117 float * in_samples_r, 118 size_t in_samples_size, 119 float * out_samples_l, 120 float * out_samples_r, 121 size_t out_samples_wanted); 122 123 /** 124 * Get latency in number of samples. 125 */ 126 unsigned int 127 stretcher_get_latency ( 128 Stretcher * self); 129 130 void 131 stretcher_set_time_ratio ( 132 Stretcher * self, 133 double ratio); 134 135 /** 136 * Perform stretching. 137 * 138 * @note Not real-time safe, does allocations. 139 * 140 * @param in_samples_size The number of input samples 141 * per channel. 142 * 143 * @return The number of output samples generated per 144 * channel. 145 */ 146 ssize_t 147 stretcher_stretch_interleaved ( 148 Stretcher * self, 149 float * in_samples, 150 size_t in_samples_size, 151 float ** _out_samples); 152 153 /** 154 * Frees the resampler. 155 */ 156 void 157 stretcher_free ( 158 Stretcher * self); 159 160 /** 161 * @} 162 */ 163 164 #endif 165