pcm_volume: implemented 32 bit support
Support 32 bit samples with software mixer.
This commit is contained in:
1
NEWS
1
NEWS
@@ -71,6 +71,7 @@ ver 0.16 (20??/??/??)
|
|||||||
* database: eliminated maximum line length
|
* database: eliminated maximum line length
|
||||||
* log: redirect stdout/stderr to /dev/null if syslog is used
|
* log: redirect stdout/stderr to /dev/null if syslog is used
|
||||||
* set the close-on-exec flag on all file descriptors
|
* set the close-on-exec flag on all file descriptors
|
||||||
|
* pcm_volume: implemented 32 bit support
|
||||||
* obey $(sysconfdir) for default mpd.conf location
|
* obey $(sysconfdir) for default mpd.conf location
|
||||||
* build with large file support by default
|
* build with large file support by default
|
||||||
* require GLib 2.12
|
* require GLib 2.12
|
||||||
|
@@ -38,4 +38,18 @@ pcm_range(int32_t sample, unsigned bits)
|
|||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the value is within the range of the provided bit size,
|
||||||
|
* and caps it if necessary.
|
||||||
|
*/
|
||||||
|
static inline int64_t
|
||||||
|
pcm_range_64(int64_t sample, unsigned bits)
|
||||||
|
{
|
||||||
|
if (G_UNLIKELY(sample < ((int64_t)-1 << (bits - 1))))
|
||||||
|
return (int64_t)-1 << (bits - 1);
|
||||||
|
if (G_UNLIKELY(sample >= ((int64_t)1 << (bits - 1))))
|
||||||
|
return ((int64_t)1 << (bits - 1)) - 1;
|
||||||
|
return sample;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -114,6 +114,29 @@ pcm_volume_change_24(int32_t *buffer, unsigned num_samples, int volume)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcm_volume_change_32(int32_t *buffer, unsigned num_samples, int volume)
|
||||||
|
{
|
||||||
|
while (num_samples > 0) {
|
||||||
|
#ifdef __i386__
|
||||||
|
/* assembly version for i386 */
|
||||||
|
int32_t sample = *buffer;
|
||||||
|
|
||||||
|
*buffer++ = pcm_volume_sample_24(sample, volume, 0);
|
||||||
|
#else
|
||||||
|
/* portable version */
|
||||||
|
int64_t sample = *buffer;
|
||||||
|
|
||||||
|
sample = (sample * volume + pcm_volume_dither() +
|
||||||
|
PCM_VOLUME_1 / 2)
|
||||||
|
/ PCM_VOLUME_1;
|
||||||
|
*buffer++ = pcm_range_64(sample, 32);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
--num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pcm_volume(void *buffer, int length,
|
pcm_volume(void *buffer, int length,
|
||||||
const struct audio_format *format,
|
const struct audio_format *format,
|
||||||
@@ -142,6 +165,11 @@ pcm_volume(void *buffer, int length,
|
|||||||
volume);
|
volume);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
pcm_volume_change_32((int32_t*)buffer, length / 4,
|
||||||
|
volume);
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user