- } /* while( ( readcount... ) */
- }
- else {
- while( ( readcount = (int) sf_read_short( sndfile, buffer, BUFFER_LEN ) ) != 0 ) {
- /* Linux/OSS -- INTEGER samples */
-#if defined (__linux__)
- /* Changing volume... */
- for( m = 0 ; m < readcount ; m++ ) {
- buffer[m] = ( buffer[m] * volume ) / 100;
- }
-
- status = (int) write( audio_fd, buffer, readcount * sizeof(short) );
- if( status == -1 ) {
- perror( PACKAGE );
- ErrorLocation( __FILE__, __LINE__ );
- goto play_audio_file_close_audio;
- }
-
- /* Solaris -- INTEGER samples */
-#elif( defined(sun) && defined(unix) )
- start_count = 0;
- output_count = read_count * sizeof(short);
-
- while( output_count > 0 ) {
- /* Write as much data as possible */
-
- /* Changing volume. */
- for( m = 0 ; m < read_count ; m++ ) {
- buffer[m] = ( buffer[m] * volume ) / 100;
- }
-
- write_count = write( audio_fd, &(buffer[start_count]), output_count );
- if( write_count > 0 ) {
- output_count -= write_count;
- start_count += write_count;
+
+ subformat = sfinfo.format & SF_FORMAT_SUBMASK;
+
+ if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
+ static float flt_buffer[BUFFER_LEN];
+ double scale;
+
+ status =
+ sf_command(sndfile, SFC_CALC_SIGNAL_MAX, &scale,
+ (int) sizeof(scale));
+ if (status == 0) {
+ fprintf(stderr,
+ "%s: Warning, sf_command() failed.\n",
+ PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ if (scale < 1e-10)
+ scale = 1.0;
+ else
+ scale = 32700.0 / scale;
+
+ while ((readcount =
+ (int) sf_read_float(sndfile, flt_buffer,
+ BUFFER_LEN)) != 0) {
+ /* Linux/OSS -- FLOAT samples */
+#if defined(__linux__)
+ for (m = 0; m < readcount; m++) {
+ /* Float to integer conversion. */
+ buffer[m] =
+ (short) (scale * flt_buffer[m]);
+ /* Changing volume */
+ buffer[m] = buffer[m] * volume / 100;
+ }
+ status =
+ (int) write(audio_fd, buffer,
+ readcount * sizeof(short));
+ if (status == -1) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ /* Solaris -- FLOAT samples */
+#elif(defined(sun) && defined(unix))
+ start_count = 0;
+ output_count = read_count * sizeof(short);
+
+ while (output_count > 0) {
+ /* Write as much data as possible */
+ for (m = 0; m < readcount; m++) {
+ /* Float to integer conversion. */
+ buffer[m] =
+ (short) (scale *
+ flt_buffer[m]);
+ /* Changing volume */
+ buffer[m] =
+ buffer[m] * volume / 100;
+ }
+
+ write_count =
+ write(audio_fd, &(buffer[start_count]),
+ output_count);
+ if (write_count > 0) {
+ output_count -= write_count;
+ start_count += write_count;
+ } else {
+ /*
+ * Give the audio output time to catch
+ * up.
+ */
+ usleep(delay_time);
+ }
+ } /* while( output_count > 0 ) */
+#endif
+ } /* while( ( readcount... ) */
+ } else {
+ while ((readcount =
+ (int) sf_read_short(sndfile, buffer,
+ BUFFER_LEN)) != 0) {
+ /* Linux/OSS -- INTEGER samples */
+#if defined(__linux__)
+ /* Changing volume... */
+ for (m = 0; m < readcount; m++)
+ buffer[m] = (buffer[m] * volume) / 100;
+
+ status = (int) write(audio_fd, buffer,
+ readcount * sizeof(short));
+ if (status == -1) {
+ perror(PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ goto play_audio_file_close_audio;
+ }
+
+ /* Solaris -- INTEGER samples */
+#elif(defined(sun) && defined(unix))
+ start_count = 0;
+ output_count = read_count * sizeof(short);
+
+ while (output_count > 0) {
+ /* Write as much data as possible */
+
+ /* Changing volume. */
+ for (m = 0; m < read_count; m++) {
+ buffer[m] =
+ (buffer[m] * volume) / 100;
+ }
+
+ write_count =
+ write(audio_fd, &(buffer[start_count]),
+ output_count);
+ if (write_count > 0) {
+ output_count -= write_count;
+ start_count += write_count;
+ } else {
+ /*
+ * Give the audio output time to catch
+ * up.
+ */
+ usleep(delay_time);
+ }
+ } /* while( output_count > 0 ) */
+#endif
+ } /* while( ( readcount... ) */
+ } /* else */
+
+play_audio_file_close_audio:
+
+ status = close(audio_fd);
+ if (status != 0) {
+ fprintf(stderr, "%s: Error, close() failed.\n", PACKAGE);
+ ErrorLocation(__FILE__, __LINE__);
+ exit(EXIT_FAILURE);