- Timestamp:
- Feb 23, 2014, 4:58:25 PM (11 years ago)
- Branches:
- feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
- Children:
- 14ac1db
- Parents:
- 222b176
- Location:
- src/io
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/io/sink_wavwrite.c
r222b176 r870ad70 25 25 26 26 #include "aubio_priv.h" 27 #include "sink_wavwrite.h"28 27 #include "fvec.h" 28 #include "fmat.h" 29 #include "io/sink_wavwrite.h" 29 30 30 31 #include <errno.h> … … 47 48 #endif 48 49 50 uint_t aubio_sink_wavwrite_open(aubio_sink_wavwrite_t *s); 51 49 52 struct _aubio_sink_wavwrite_t { 50 53 char_t *path; … … 73 76 aubio_sink_wavwrite_t * new_aubio_sink_wavwrite(char_t * path, uint_t samplerate) { 74 77 aubio_sink_wavwrite_t * s = AUBIO_NEW(aubio_sink_wavwrite_t); 75 unsigned char buf[5];76 uint_t byterate, blockalign;77 78 78 79 if (path == NULL) { … … 86 87 87 88 s->path = path; 88 s->samplerate = samplerate;89 89 s->max_size = MAX_SIZE; 90 s->channels = 1;91 90 s->bitspersample = 16; 92 91 s->total_frames_written = 0; 93 92 94 /* set output format */ 95 s->fid = fopen((const char *)path, "wb"); 96 if (!s->fid) { 97 AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, strerror(errno)); 98 goto beach; 99 } 100 101 // ChunkID 102 fwrite("RIFF", 4, 1, s->fid); 103 104 // ChunkSize (0 for now, actual size will be written in _close) 105 fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid); 106 107 // Format 108 fwrite("WAVE", 4, 1, s->fid); 109 110 // Subchunk1ID 111 fwrite("fmt ", 4, 1, s->fid); 112 113 // Subchunk1Size 114 fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid); 115 116 // AudioFormat 117 fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid); 118 119 // NumChannels 120 fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid); 121 122 // SampleRate 123 fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid); 124 125 // ByteRate 126 byterate = s->samplerate * s->channels * s->bitspersample / 8; 127 fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid); 128 129 // BlockAlign 130 blockalign = s->channels * s->bitspersample / 8; 131 fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid); 132 133 // BitsPerSample 134 fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid); 135 136 // Subchunk2ID 137 fwrite("data", 4, 1, s->fid); 138 139 // Subchunk1Size (0 for now, actual size will be written in _close) 140 fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid); 141 142 s->scratch_size = s->max_size * s->channels; 143 /* allocate data for de/interleaving reallocated when needed. */ 144 if (s->scratch_size >= MAX_SIZE * MAX_CHANNELS) { 145 AUBIO_ERR("sink_wavwrite: %d x %d exceeds maximum buffer size %d\n", 146 s->max_size, s->channels, MAX_CHANNELS * MAX_CHANNELS); 147 AUBIO_FREE(s); 148 return NULL; 149 } 150 s->scratch_data = AUBIO_ARRAY(unsigned short,s->scratch_size); 93 s->samplerate = 0; 94 s->channels = 0; 95 96 // negative samplerate given, abort 97 if ((sint_t)samplerate < 0) goto beach; 98 // zero samplerate given. do not open yet 99 if ((sint_t)samplerate == 0) return s; 100 101 s->samplerate = samplerate; 102 s->channels = 1; 103 104 if (aubio_sink_wavwrite_open(s) != AUBIO_OK) { 105 // open failed, abort 106 goto beach; 107 } 151 108 152 109 return s; 153 154 110 beach: 155 111 //AUBIO_ERR("sink_wavwrite: failed creating %s with samplerate %dHz\n", … … 159 115 } 160 116 117 uint_t aubio_sink_wavwrite_preset_samplerate(aubio_sink_wavwrite_t *s, uint_t samplerate) 118 { 119 if ((sint_t)(samplerate) <= 0) return AUBIO_FAIL; 120 s->samplerate = samplerate; 121 // automatically open when both samplerate and channels have been set 122 if (s->samplerate != 0 && s->channels != 0) { 123 return aubio_sink_wavwrite_open(s); 124 } 125 return AUBIO_OK; 126 } 127 128 uint_t aubio_sink_wavwrite_preset_channels(aubio_sink_wavwrite_t *s, uint_t channels) 129 { 130 if ((sint_t)(channels) <= 0) return AUBIO_FAIL; 131 s->channels = channels; 132 // automatically open when both samplerate and channels have been set 133 if (s->samplerate != 0 && s->channels != 0) { 134 return aubio_sink_wavwrite_open(s); 135 } 136 return AUBIO_OK; 137 } 138 139 uint_t aubio_sink_wavwrite_get_samplerate(aubio_sink_wavwrite_t *s) 140 { 141 return s->samplerate; 142 } 143 144 uint_t aubio_sink_wavwrite_get_channels(aubio_sink_wavwrite_t *s) 145 { 146 return s->channels; 147 } 148 149 uint_t aubio_sink_wavwrite_open(aubio_sink_wavwrite_t *s) { 150 unsigned char buf[5]; 151 uint_t byterate, blockalign; 152 153 /* open output file */ 154 s->fid = fopen((const char *)s->path, "wb"); 155 if (!s->fid) { 156 AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, strerror(errno)); 157 goto beach; 158 } 159 160 // ChunkID 161 fwrite("RIFF", 4, 1, s->fid); 162 163 // ChunkSize (0 for now, actual size will be written in _close) 164 fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid); 165 166 // Format 167 fwrite("WAVE", 4, 1, s->fid); 168 169 // Subchunk1ID 170 fwrite("fmt ", 4, 1, s->fid); 171 172 // Subchunk1Size 173 fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid); 174 175 // AudioFormat 176 fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid); 177 178 // NumChannels 179 fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid); 180 181 // SampleRate 182 fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid); 183 184 // ByteRate 185 byterate = s->samplerate * s->channels * s->bitspersample / 8; 186 fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid); 187 188 // BlockAlign 189 blockalign = s->channels * s->bitspersample / 8; 190 fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid); 191 192 // BitsPerSample 193 fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid); 194 195 // Subchunk2ID 196 fwrite("data", 4, 1, s->fid); 197 198 // Subchunk1Size (0 for now, actual size will be written in _close) 199 fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid); 200 201 s->scratch_size = s->max_size * s->channels; 202 /* allocate data for de/interleaving reallocated when needed. */ 203 if (s->scratch_size >= MAX_SIZE * MAX_CHANNELS) { 204 AUBIO_ERR("sink_wavwrite: %d x %d exceeds SIZE maximum buffer size %d\n", 205 s->max_size, s->channels, MAX_SIZE * MAX_CHANNELS); 206 goto beach; 207 } 208 s->scratch_data = AUBIO_ARRAY(unsigned short,s->scratch_size); 209 210 return AUBIO_OK; 211 212 beach: 213 return AUBIO_FAIL; 214 } 215 161 216 162 217 void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t *s, fvec_t * write_data, uint_t write){ … … 177 232 AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, " 178 233 "but only %d could be written\n", write, s->path, written_frames); 234 } 235 s->total_frames_written += written_frames; 236 return; 237 } 238 239 void aubio_sink_wavwrite_do_multi(aubio_sink_wavwrite_t *s, fmat_t * write_data, uint_t write){ 240 uint_t c = 0, i = 0, written_frames = 0; 241 242 if (write > s->max_size) { 243 AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, " 244 "but only %d can be written at a time\n", write, s->path, s->max_size); 245 write = s->max_size; 246 } 247 248 for (c = 0; c < s->channels; c++) { 249 for (i = 0; i < write; i++) { 250 s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[c][i])); 251 } 252 } 253 written_frames = fwrite(s->scratch_data, 2, write * s->channels, s->fid); 254 255 if (written_frames != write * s->channels) { 256 AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, " 257 "but only %d could be written\n", write, s->path, written_frames / s->channels); 179 258 } 180 259 s->total_frames_written += written_frames; -
src/io/sink_wavwrite.h
r222b176 r870ad70 24 24 /** \file 25 25 26 Write to file using [libsndfile](http://www.mega-nerd.com/libsndfile/)26 Write to file using native file writer. 27 27 28 28 Avoid including this file directly! Prefer using ::aubio_sink_t instead to … … 39 39 #endif 40 40 41 /** sink_wavwrite object */ 41 42 typedef struct _aubio_sink_wavwrite_t aubio_sink_wavwrite_t; 42 43 … … 52 53 Creates a new sink object. 53 54 55 If samplerate is set to 0, the creation of the file will be delayed until 56 both ::aubio_sink_preset_samplerate and ::aubio_sink_preset_channels have 57 been called. 58 54 59 */ 55 60 aubio_sink_wavwrite_t * new_aubio_sink_wavwrite(char_t * uri, uint_t samplerate); 61 62 /** 63 64 preset sink samplerate 65 66 \param s sink, created with ::new_aubio_sink_wavwrite 67 \param samplerate samplerate to preset the sink to, in Hz 68 69 \return 0 on success, 1 on error 70 71 Preset the samplerate of the sink. The file should have been created using a 72 samplerate of 0. 73 74 The file will be opened only when both samplerate and channels have been set. 75 76 */ 77 uint_t aubio_sink_wavwrite_preset_samplerate(aubio_sink_wavwrite_t *s, uint_t samplerate); 78 79 /** 80 81 preset sink channels 82 83 \param s sink, created with ::new_aubio_sink_wavwrite 84 \param channels number of channels to preset the sink to 85 86 \return 0 on success, 1 on error 87 88 Preset the samplerate of the sink. The file should have been created using a 89 samplerate of 0. 90 91 The file will be opened only when both samplerate and channels have been set. 92 93 */ 94 uint_t aubio_sink_wavwrite_preset_channels(aubio_sink_wavwrite_t *s, uint_t channels); 95 96 /** 97 98 get samplerate of sink object 99 100 \param s sink object, created with ::new_aubio_sink_wavwrite 101 \return samplerate, in Hz 102 103 */ 104 uint_t aubio_sink_wavwrite_get_samplerate(aubio_sink_wavwrite_t *s); 105 106 /** 107 108 get channels of sink object 109 110 \param s sink object, created with ::new_aubio_sink_wavwrite 111 \return number of channels 112 113 */ 114 uint_t aubio_sink_wavwrite_get_channels(aubio_sink_wavwrite_t *s); 56 115 57 116 /** … … 65 124 */ 66 125 void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t * s, fvec_t * write_data, uint_t write); 126 127 /** 128 129 write polyphonic vector of length hop_size to sink 130 131 \param s sink, created with ::new_aubio_sink_wavwrite 132 \param write_data ::fmat_t samples to write to sink 133 \param write number of frames to write 134 135 */ 136 void aubio_sink_wavwrite_do_multi(aubio_sink_wavwrite_t * s, fmat_t * write_data, uint_t write); 67 137 68 138 /**
Note: See TracChangeset
for help on using the changeset viewer.