comparison libinterp/dldfcn/audioread.cc @ 19709:793d295fed4d

Fix sndfile bit width handling in audio functions * audioread.cc (Faudioread, Faudioinfo): Fix decoding of audio format bit width from sndfile format field. (Faudiowrite): Mask format field properly when setting audio output bit width. Use unsigned format for 8-bit WAV output.
author Mike Miller <mtmiller@ieee.org>
date Sun, 01 Feb 2015 20:46:37 -0500
parents 72304a4e010a
children 4197fc428c7d
comparison
equal deleted inserted replaced
19708:b3363c531662 19709:793d295fed4d
164 if (error_state) 164 if (error_state)
165 return retval; 165 return retval;
166 166
167 if (type == "native") 167 if (type == "native")
168 { 168 {
169 if (info.format & SF_FORMAT_PCM_S8) 169 switch (info.format & SF_FORMAT_SUBMASK)
170 ret_audio = int8NDArray (audio * 127); 170 {
171 else if (info.format & SF_FORMAT_PCM_U8) 171 case SF_FORMAT_PCM_S8:
172 ret_audio = uint8NDArray (audio * 127 + 127); 172 ret_audio = int8NDArray (audio * 127);
173 else if (info.format & SF_FORMAT_PCM_16) 173 break;
174 ret_audio = int16NDArray (audio * 32767); 174 case SF_FORMAT_PCM_U8:
175 else if (info.format & SF_FORMAT_PCM_24) 175 ret_audio = uint8NDArray (audio * 127 + 127);
176 ret_audio = int32NDArray (audio * 8388608); 176 break;
177 else if (info.format & SF_FORMAT_PCM_32) 177 case SF_FORMAT_PCM_16:
178 ret_audio = int32NDArray (audio * 2147483648); 178 ret_audio = int16NDArray (audio * 32767);
179 else 179 break;
180 ret_audio = audio; 180 case SF_FORMAT_PCM_24:
181 ret_audio = int32NDArray (audio * 8388608);
182 break;
183 case SF_FORMAT_PCM_32:
184 ret_audio = int32NDArray (audio * 2147483648);
185 break;
186 default:
187 ret_audio = audio;
188 break;
189 }
181 } 190 }
182 else 191 else
183 ret_audio = audio; 192 ret_audio = audio;
184 } 193 }
185 else 194 else
353 // float quality = 0.75; 362 // float quality = 0.75;
354 for (int i = 3; i < nargin; i += 2) 363 for (int i = 3; i < nargin; i += 2)
355 { 364 {
356 if (args(i).string_value () == "BitsPerSample") 365 if (args(i).string_value () == "BitsPerSample")
357 { 366 {
367 info.format &= ~SF_FORMAT_SUBMASK;
358 int bits = args(i + 1).int_value (); 368 int bits = args(i + 1).int_value ();
359 if (bits == 8) 369 if (bits == 8)
360 info.format |= SF_FORMAT_PCM_S8; 370 {
371 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
372 info.format |= SF_FORMAT_PCM_U8;
373 else
374 info.format |= SF_FORMAT_PCM_S8;
375 }
361 else if (bits == 16) 376 else if (bits == 16)
362 info.format |= SF_FORMAT_PCM_16; 377 info.format |= SF_FORMAT_PCM_16;
363 else if (bits == 24) 378 else if (bits == 24)
364 info.format |= SF_FORMAT_PCM_24; 379 info.format |= SF_FORMAT_PCM_24;
365 else if (bits == 32) 380 else if (bits == 32)
489 double dframes = info.frames; 504 double dframes = info.frames;
490 double drate = info.samplerate; 505 double drate = info.samplerate;
491 result.assign ("Duration", dframes / drate); 506 result.assign ("Duration", dframes / drate);
492 507
493 int bits; 508 int bits;
494 if (info.format & SF_FORMAT_PCM_S8) 509 switch (info.format & SF_FORMAT_SUBMASK)
495 bits = 8; 510 {
496 else if (info.format & SF_FORMAT_PCM_U8) 511 case SF_FORMAT_PCM_S8:
497 bits = 8; 512 bits = 8;
498 else if (info.format & SF_FORMAT_PCM_16) 513 break;
499 bits = 16; 514 case SF_FORMAT_PCM_U8:
500 else if (info.format & SF_FORMAT_PCM_24) 515 bits = 8;
501 bits = 24; 516 break;
502 else if (info.format & SF_FORMAT_PCM_32) 517 case SF_FORMAT_PCM_16:
503 bits = 32; 518 bits = 16;
504 else 519 break;
505 bits = -1; 520 case SF_FORMAT_PCM_24:
521 bits = 24;
522 break;
523 case SF_FORMAT_PCM_32:
524 bits = 32;
525 break;
526 default:
527 bits = -1;
528 break;
529 }
506 530
507 result.assign ("BitsPerSample", bits); 531 result.assign ("BitsPerSample", bits);
508 result.assign ("BitRate", -1); 532 result.assign ("BitRate", -1);
509 result.assign ("Title", sf_get_string (file, SF_STR_TITLE)); 533 result.assign ("Title", sf_get_string (file, SF_STR_TITLE));
510 result.assign ("Artist", sf_get_string (file, SF_STR_ARTIST)); 534 result.assign ("Artist", sf_get_string (file, SF_STR_ARTIST));