1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (C) 4Front Technologies 1996-2008. 23 * 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* 29 * Purpose: GRC library version 3.1 internal definitions 30 * 31 * GRC3 is a high quality sample rate conversion module that uses fixed point 32 * arithmetic. 33 */ 34 35 #ifndef AUDIO_GRC3_H 36 #define AUDIO_GRC3_H 37 38 #define GRC3_MAXHISTORY 4096 39 40 #ifdef __cplusplus 41 extern "C" 42 { 43 #endif 44 45 typedef struct grc3state { 46 uint32_t srcrate; 47 uint32_t dstrate; 48 uint32_t ptr; 49 uint32_t ptr_incv; 50 51 uint32_t sat; 52 uint32_t filtfactor; 53 int32_t *historyptr; 54 int32_t dummy_pad1; 55 56 int32_t history[GRC3_MAXHISTORY * 2 + 1]; 57 58 uint32_t outsz; 59 } grc3state_t; 60 61 62 /* BEGIN CSTYLED */ 63 /***************************************************************************** 64 65 Tutorial on how to use GRC3 rate conversion 66 67 1. First, you create an instance of grc3state_t for each channel. If you 68 are working with stereo files - you will need 2 of such instances, 69 for quadro - 4. 70 71 The instances may be allocated in either static or dynamic memory - that 72 makes no difference to the convertor. So, if your program has to process 73 one stereo stream, there's no reason why should you use malloc/free to 74 allocate/deallocate structures. Also, in device drivers, you can 75 use static variables as well: 76 77 static grc3state_t grc[2]; // for two channels 78 79 80 2. Before starting any conversion, grc3state_t instances should be initialized 81 properly, and you do this with grc3_setup function. Function itself does 82 not allocate additional memory or change anything except grc3state_t 83 structure, so this is thread safe, and you don't have to do additional 84 "deinitialization". 85 86 If you are doing interleaved audio (stereo/quadro/whatever) conversion, 87 you should do setup on each of the channels, and should have separate 88 instance of grc3state_t for each channel. As you will understand further, 89 such conversion is done separately. And now, the setup function: 90 91 int grc3_setup( grc3state_t *grc, 92 uint32_t fromRate, 93 uint32_t toRate ); 94 95 grc - pointer to grc3state_t instance 96 fromRate - source sample rate 97 toRate - destination sample rate 98 99 Note, that sample rates itself are not important - the important thing 100 is ratio between those sample rates. So, for example, if you have to 101 convert from 24000Hz to 48000Hz, it's ok to write: 102 103 grc3_setup( &grc[0], 240, 480 ); 104 105 Sometimes (in MIDI synths) it would be desired to use fractional sample 106 rates. For example, setup for conversion from 33100.78 to 48000 may look 107 like this: 108 109 grc3_setup( &grc[0], 3310078, 4800000); 110 111 Note, that on stereo, GRC3 setup will look like this: 112 113 static grc3state_t grc[2]; 114 115 // ... 116 117 grc3_setup( &grc[0], 3310078, 4800000) 118 grc3_setup( &grc[1], 3310078, 4800000); 119 120 121 Note, that you should not rely on grc3_setup's fast execution or any 122 execution timing. It may contain some massive arithmetic and even huge 123 loops, so avoid putting grc3_setup to inner loops and calling in 124 latency-dependent code. 125 126 127 3. Next, before running a stream through grc3_convert function, you should 128 reset each of grc3state_t instance used: 129 130 void grc3_reset(grc3state_t *grc); 131 132 133 grc - pointer to GRC3 instance variable 134 135 So, for stereo, this appears to be: 136 137 static grc3state_t grc[2]; 138 139 // ... 140 141 grc3_reset( &grc[0] ); 142 grc3_reset( &grc[1] ); 143 144 145 4. Finally, doing conversion is easy: 146 147 void grc3_convert( grc3state_t *grc, 148 int domain, 149 int quality, 150 const void *src, 151 void *dst, 152 int maxInSize, 153 int maxOutSize, 154 int interleave, 155 int offset ); 156 157 158 grc - pointer to initialized grc3state_t instance; you 159 can specify NULL to check whether a particular 160 domain/quality pair is supported, check return value 161 162 quality - quality to use for conversion, supported values are: 163 164 0 - D lowest quality (normally equals to low quality) 165 1 - L low quality (spline interpolation) 166 2 - M medium quality (lagrange interpolation) 167 3 - H high quality 168 4 - HX high quality (high quality with extra precision) 169 5 - P production quality 170 171 6 - PX production quality (prod quality with extra precision) 172 (PX is currently disabled because it causes a crash) 173 174 src - source audio buffer 175 176 dst - destination audio buffer; 177 178 maxInSize - size of input buffer (in samples per channel!) 179 180 maxOutSize - size of output buffer (in samples per channel!) 181 (will never overrun this size) 182 183 interleave - interleave factor; for MONO or non-interleaved data 184 it should be equal to 1; 185 186 2 - STEREO interleaved audio 187 4 - QUADRO interleaved audio 188 189 So, basically, this parameter should be equal to number 190 of interleaved channels 191 192 offset - number of interleaved channel currently processing, 193 starting from 0; for MONO or non-interleaved data 194 it should be equal to 0 195 196 197 For unsupported quality values, it will fall back to 198 "D" quality (the lowest one) 199 200 also on return it sets: 201 202 grc->outsz == number of output samples 203 204 Note, that if quality is not supported, 205 calling the function with real data will fall back 206 to the worst quality available. 207 208 Note that this version of GRC3 only supports 24-bit 209 native endian. (Modified by Sun for performance.) 210 211 212 213 5. Interleaved processing of N channels is done like this: 214 215 216 static grc3state_t grc[N]; 217 int t; 218 219 //... 220 221 222 for(t=0; t<N; t++) 223 { 224 grc3_setup( &grc[t], 22050, 48000 ); 225 226 grc3_reset( &grc[t] ); 227 } 228 229 230 //... 231 232 while (...) { 233 234 for(t = 0; t < N; t++) { 235 grc3_convert(&grc[t], // instance pointer 236 4, // quality 237 in_buffer, // input buffer 238 out_buffer, // input buffer 239 in_samples_count, // number of samples 240 // in in_buffer 241 2048, // size of out_buffer 242 N, t // num of channels, channel# 243 ); 244 } 245 246 247 // Normally, for interleaved data, ->outsz of all instances will 248 // be the same for the same stream 249 250 put_sound_somewhere(out_buffer, 251 grc[0]->outsz * N * sizeof(out_buffer[0]) ); 252 } 253 254 255 6. If you use the same storage and the same setup for processing few separate 256 non-related sounds, to prevent the feedback of sound1's tail to sound2's 257 beginning - do grc3_reset on the state instances before calling 258 grc_convert. 259 260 ***************************************************************************** 261 */ 262 /* END CSTYLED */ 263 264 void grc3_setup(grc3state_t *, uint32_t fromRate, uint32_t toRate); 265 266 void grc3_reset(grc3state_t *); 267 268 void grc3_convert(grc3state_t *, int quality, 269 const void *src, void *dst, int sz, int bufsz, int inc, int offset); 270 271 #ifdef __cplusplus 272 }; 273 #endif 274 275 #endif /* AUDIO_GRC3_H */ 276