pcm_utils: moved code to pcm_volume.c
Moved the software volume code to a separate library.
This commit is contained in:
		| @@ -50,6 +50,7 @@ mpd_headers = \ | ||||
| 	path.h \ | ||||
| 	mapper.h \ | ||||
| 	pcm_utils.h \ | ||||
| 	pcm_volume.h \ | ||||
| 	pcm_channels.h \ | ||||
| 	pcm_resample.h \ | ||||
| 	pcm_dither.h \ | ||||
| @@ -129,6 +130,7 @@ mpd_SOURCES = \ | ||||
| 	path.c \ | ||||
| 	mapper.c \ | ||||
| 	pcm_utils.c \ | ||||
| 	pcm_volume.c \ | ||||
| 	pcm_channels.c \ | ||||
| 	pcm_resample.c \ | ||||
| 	pcm_dither.c \ | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
| #include "pcm_utils.h" | ||||
| #include "pcm_channels.h" | ||||
| #include "pcm_prng.h" | ||||
| #include "pcm_volume.h" | ||||
| #include "conf.h" | ||||
| #include "audio_format.h" | ||||
|  | ||||
| @@ -30,92 +31,6 @@ | ||||
| #undef G_LOG_DOMAIN | ||||
| #define G_LOG_DOMAIN "pcm" | ||||
|  | ||||
| static inline int | ||||
| pcm_dither(void) | ||||
| { | ||||
| 	static unsigned long state; | ||||
| 	uint32_t r; | ||||
|  | ||||
| 	r = state = prng(state); | ||||
|  | ||||
| 	return (r & 511) - ((r >> 9) & 511); | ||||
| } | ||||
|  | ||||
| static void | ||||
| pcm_volume_change_8(int8_t *buffer, unsigned num_samples, int volume) | ||||
| { | ||||
| 	while (num_samples > 0) { | ||||
| 		int32_t sample = *buffer; | ||||
|  | ||||
| 		sample = (sample * volume + pcm_dither() + PCM_VOLUME_1 / 2) | ||||
| 			/ PCM_VOLUME_1; | ||||
|  | ||||
| 		*buffer++ = pcm_range(sample, 8); | ||||
| 		--num_samples; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| pcm_volume_change_16(int16_t *buffer, unsigned num_samples, int volume) | ||||
| { | ||||
| 	while (num_samples > 0) { | ||||
| 		int32_t sample = *buffer; | ||||
|  | ||||
| 		sample = (sample * volume + pcm_dither() + PCM_VOLUME_1 / 2) | ||||
| 			/ PCM_VOLUME_1; | ||||
|  | ||||
| 		*buffer++ = pcm_range(sample, 16); | ||||
| 		--num_samples; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| pcm_volume_change_24(int32_t *buffer, unsigned num_samples, int volume) | ||||
| { | ||||
| 	while (num_samples > 0) { | ||||
| 		int64_t sample = *buffer; | ||||
|  | ||||
| 		sample = (sample * volume + pcm_dither() + PCM_VOLUME_1 / 2) | ||||
| 			/ PCM_VOLUME_1; | ||||
|  | ||||
| 		*buffer++ = pcm_range(sample, 24); | ||||
| 		--num_samples; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void pcm_volume(char *buffer, int bufferSize, | ||||
| 		const struct audio_format *format, | ||||
| 		int volume) | ||||
| { | ||||
| 	if (volume == PCM_VOLUME_1) | ||||
| 		return; | ||||
|  | ||||
| 	if (volume <= 0) { | ||||
| 		memset(buffer, 0, bufferSize); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	switch (format->bits) { | ||||
| 	case 8: | ||||
| 		pcm_volume_change_8((int8_t *)buffer, bufferSize, volume); | ||||
| 		break; | ||||
|  | ||||
| 	case 16: | ||||
| 		pcm_volume_change_16((int16_t *)buffer, bufferSize / 2, | ||||
| 				     volume); | ||||
| 		break; | ||||
|  | ||||
| 	case 24: | ||||
| 		pcm_volume_change_24((int32_t*)buffer, bufferSize / 4, | ||||
| 				     volume); | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		g_error("%u bits not supported by pcm_volume!\n", | ||||
| 			format->bits); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| pcm_add_8(int8_t *buffer1, const int8_t *buffer2, | ||||
| 	  unsigned num_samples, int volume1, int volume2) | ||||
|   | ||||
| @@ -29,11 +29,6 @@ | ||||
|  | ||||
| struct audio_format; | ||||
|  | ||||
| enum { | ||||
| 	/** this value means "100% volume" */ | ||||
| 	PCM_VOLUME_1 = 1000, | ||||
| }; | ||||
|  | ||||
| struct pcm_convert_state { | ||||
| 	struct pcm_resample_state resample; | ||||
|  | ||||
| @@ -57,20 +52,6 @@ pcm_range(int32_t sample, unsigned bits) | ||||
| 	return sample; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Converts a float value (0.0 = silence, 1.0 = 100% volume) to an | ||||
|  * integer volume value (1000 = 100%). | ||||
|  */ | ||||
| static inline int | ||||
| pcm_float_to_volume(float volume) | ||||
| { | ||||
| 	return volume * PCM_VOLUME_1 + 0.5; | ||||
| } | ||||
|  | ||||
| void pcm_volume(char *buffer, int bufferSize, | ||||
| 		const struct audio_format *format, | ||||
| 		int volume); | ||||
|  | ||||
| void pcm_mix(char *buffer1, const char *buffer2, size_t size, | ||||
|              const struct audio_format *format, float portion1); | ||||
|  | ||||
|   | ||||
							
								
								
									
										105
									
								
								src/pcm_volume.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/pcm_volume.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| /* | ||||
|  * Copyright (C) 2003-2009 The Music Player Daemon Project | ||||
|  * http://www.musicpd.org | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
|  | ||||
| #include "pcm_volume.h" | ||||
| #include "pcm_utils.h" | ||||
| #include "audio_format.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #undef G_LOG_DOMAIN | ||||
| #define G_LOG_DOMAIN "pcm_volume" | ||||
|  | ||||
| static void | ||||
| pcm_volume_change_8(int8_t *buffer, unsigned num_samples, int volume) | ||||
| { | ||||
| 	while (num_samples > 0) { | ||||
| 		int32_t sample = *buffer; | ||||
|  | ||||
| 		sample = (sample * volume + pcm_dither() + PCM_VOLUME_1 / 2) | ||||
| 			/ PCM_VOLUME_1; | ||||
|  | ||||
| 		*buffer++ = pcm_range(sample, 8); | ||||
| 		--num_samples; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| pcm_volume_change_16(int16_t *buffer, unsigned num_samples, int volume) | ||||
| { | ||||
| 	while (num_samples > 0) { | ||||
| 		int32_t sample = *buffer; | ||||
|  | ||||
| 		sample = (sample * volume + pcm_dither() + PCM_VOLUME_1 / 2) | ||||
| 			/ PCM_VOLUME_1; | ||||
|  | ||||
| 		*buffer++ = pcm_range(sample, 16); | ||||
| 		--num_samples; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| pcm_volume_change_24(int32_t *buffer, unsigned num_samples, int volume) | ||||
| { | ||||
| 	while (num_samples > 0) { | ||||
| 		int64_t sample = *buffer; | ||||
|  | ||||
| 		sample = (sample * volume + pcm_dither() + PCM_VOLUME_1 / 2) | ||||
| 			/ PCM_VOLUME_1; | ||||
|  | ||||
| 		*buffer++ = pcm_range(sample, 24); | ||||
| 		--num_samples; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| pcm_volume(char *buffer, int bufferSize, | ||||
| 	   const struct audio_format *format, | ||||
| 	   int volume) | ||||
| { | ||||
| 	if (volume == PCM_VOLUME_1) | ||||
| 		return; | ||||
|  | ||||
| 	if (volume <= 0) { | ||||
| 		memset(buffer, 0, bufferSize); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	switch (format->bits) { | ||||
| 	case 8: | ||||
| 		pcm_volume_change_8((int8_t *)buffer, bufferSize, volume); | ||||
| 		break; | ||||
|  | ||||
| 	case 16: | ||||
| 		pcm_volume_change_16((int16_t *)buffer, bufferSize / 2, | ||||
| 				     volume); | ||||
| 		break; | ||||
|  | ||||
| 	case 24: | ||||
| 		pcm_volume_change_24((int32_t*)buffer, bufferSize / 4, | ||||
| 				     volume); | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		g_error("%u bits not supported by pcm_volume!\n", | ||||
| 			format->bits); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/pcm_volume.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/pcm_volume.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* | ||||
|  * Copyright (C) 2003-2009 The Music Player Daemon Project | ||||
|  * http://www.musicpd.org | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
|  | ||||
| #ifndef PCM_VOLUME_H | ||||
| #define PCM_VOLUME_H | ||||
|  | ||||
| #include "pcm_prng.h" | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| enum { | ||||
| 	/** this value means "100% volume" */ | ||||
| 	PCM_VOLUME_1 = 1000, | ||||
| }; | ||||
|  | ||||
| struct audio_format; | ||||
|  | ||||
| /** | ||||
|  * Converts a float value (0.0 = silence, 1.0 = 100% volume) to an | ||||
|  * integer volume value (1000 = 100%). | ||||
|  */ | ||||
| static inline int | ||||
| pcm_float_to_volume(float volume) | ||||
| { | ||||
| 	return volume * PCM_VOLUME_1 + 0.5; | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| pcm_dither(void) | ||||
| { | ||||
| 	static unsigned long state; | ||||
| 	uint32_t r; | ||||
|  | ||||
| 	r = state = prng(state); | ||||
|  | ||||
| 	return (r & 511) - ((r >> 9) & 511); | ||||
| } | ||||
|  | ||||
| void | ||||
| pcm_volume(char *buffer, int bufferSize, | ||||
| 	   const struct audio_format *format, | ||||
| 	   int volume); | ||||
|  | ||||
| #endif | ||||
| @@ -22,7 +22,7 @@ | ||||
| #include "tag.h" | ||||
| #include "song.h" | ||||
| #include "idle.h" | ||||
| #include "pcm_utils.h" | ||||
| #include "pcm_volume.h" | ||||
| #include "main.h" | ||||
|  | ||||
| #include <assert.h> | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| #include "player_control.h" | ||||
| #include "decoder_control.h" | ||||
| #include "audio.h" | ||||
| #include "pcm_utils.h" | ||||
| #include "pcm_volume.h" | ||||
| #include "path.h" | ||||
| #include "event_pipe.h" | ||||
| #include "crossfade.h" | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| #include "replay_gain.h" | ||||
| #include "conf.h" | ||||
| #include "audio_format.h" | ||||
| #include "pcm_utils.h" | ||||
| #include "pcm_volume.h" | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <stdlib.h> | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| #include "conf.h" | ||||
| #include "player_control.h" | ||||
| #include "idle.h" | ||||
| #include "pcm_utils.h" | ||||
| #include "pcm_volume.h" | ||||
| #include "config.h" | ||||
| #include "audio.h" | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann