mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	commit liboil porting changes
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/liboil-test@344 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									0c9873e5b3
								
							
						
					
					
						commit
						e1f008f2a3
					
				
					 23 changed files with 917 additions and 232 deletions
				
			
		| 
						 | 
					@ -542,7 +542,7 @@ mainloop_test_SOURCES = mainloop-test.c
 | 
				
			||||||
mainloop_test_CFLAGS = $(AM_CFLAGS)
 | 
					mainloop_test_CFLAGS = $(AM_CFLAGS)
 | 
				
			||||||
mainloop_test_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la libpolyp-@PA_MAJORMINOR@.la
 | 
					mainloop_test_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la libpolyp-@PA_MAJORMINOR@.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
voltest_SOURCES = voltest.c sample.c
 | 
					voltest_SOURCES = voltest.c volume.c
 | 
				
			||||||
voltest_CFLAGS = $(AM_CFLAGS)
 | 
					voltest_CFLAGS = $(AM_CFLAGS)
 | 
				
			||||||
voltest_LDADD = $(AM_LDADD)
 | 
					voltest_LDADD = $(AM_LDADD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										140
									
								
								polyp/channelmap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								polyp/channelmap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,140 @@
 | 
				
			||||||
 | 
					/* $Id$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***
 | 
				
			||||||
 | 
					  This file is part of polypaudio.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					  it under the terms of the GNU Lesser General Public License as published
 | 
				
			||||||
 | 
					  by the Free Software Foundation; either version 2 of the License,
 | 
				
			||||||
 | 
					  or (at your option) any later version.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio 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 Lesser General Public License
 | 
				
			||||||
 | 
					  along with polypaudio; if not, write to the Free Software
 | 
				
			||||||
 | 
					  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
				
			||||||
 | 
					  USA.
 | 
				
			||||||
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include <config.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "channelmap.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init(struct pa_channel_map *m) {
 | 
				
			||||||
 | 
					    unsigned c;
 | 
				
			||||||
 | 
					    assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (c = 0; c < PA_CHANNELS_MAX; c++)
 | 
				
			||||||
 | 
					        m->map[c] = PA_CHANNEL_POSITION_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return m;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init_mono(struct pa_channel_map *m) {
 | 
				
			||||||
 | 
					    assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_channel_map_init(m);
 | 
				
			||||||
 | 
					    m->map[0] = PA_CHANNEL_POSITION_MONO;
 | 
				
			||||||
 | 
					    return m;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init_stereo(struct pa_channel_map *m) {
 | 
				
			||||||
 | 
					    assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_channel_map_init(m);
 | 
				
			||||||
 | 
					    m->map[0] = PA_CHANNEL_POSITION_LEFT;
 | 
				
			||||||
 | 
					    m->map[1] = PA_CHANNEL_POSITION_RIGHT;
 | 
				
			||||||
 | 
					    return m;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init_auto(struct pa_channel_map *m, int channels) {
 | 
				
			||||||
 | 
					    assert(m);
 | 
				
			||||||
 | 
					    assert(channels > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_channel_map_init(m);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    switch (channels) {
 | 
				
			||||||
 | 
					        case 1:
 | 
				
			||||||
 | 
					            m->map[0] = PA_CHANNEL_POSITION_MONO;
 | 
				
			||||||
 | 
					            return m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case 8:
 | 
				
			||||||
 | 
					            m->mpa[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
 | 
				
			||||||
 | 
					            m->mpa[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
 | 
				
			||||||
 | 
					            /* Fall through */
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        case 6:
 | 
				
			||||||
 | 
					            m->mpa[5] = PA_CHANNEL_POSITION_LFE;
 | 
				
			||||||
 | 
					            /* Fall through */
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        case 5:
 | 
				
			||||||
 | 
					            m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
 | 
				
			||||||
 | 
					            /* Fall through */
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        case 4:
 | 
				
			||||||
 | 
					            m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
 | 
				
			||||||
 | 
					            m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
 | 
				
			||||||
 | 
					            /* Fall through */
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        case 2:
 | 
				
			||||||
 | 
					            m->map[0] = PA_CHANNEL_MAP_FRONT_LEFT;
 | 
				
			||||||
 | 
					            m->map[1] = PA_CHANNEL_MAP_FRONT_RIGHT;
 | 
				
			||||||
 | 
					            return m;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char* pa_channel_position_to_string(pa_channel_position_t pos) {
 | 
				
			||||||
 | 
					    const char *const table[] = {
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_MONO] = "mono",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center",
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left",
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right",
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center",
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left",
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_LFE] = "lfe",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center",
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center",
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left",
 | 
				
			||||||
 | 
					        [PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return table[pos];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pa_channel_map_equal(struct pa_channel_map *a, struct pa_channel_map *b, int channels) {
 | 
				
			||||||
 | 
					    char c;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					    assert(b);
 | 
				
			||||||
 | 
					    assert(channels > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (channels > PA_CHANNELS_MAX)
 | 
				
			||||||
 | 
					        channels = PA_CHANNELS_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (c = 0; c < channels; c++)
 | 
				
			||||||
 | 
					        if (a->map[c] != b->map[c])
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								polyp/channelmap.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								polyp/channelmap.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					#ifndef foochannelmaphfoo
 | 
				
			||||||
 | 
					#define foochannelmaphfoo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* $Id$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***
 | 
				
			||||||
 | 
					  This file is part of polypaudio.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					  it under the terms of the GNU Lesser General Public License as published
 | 
				
			||||||
 | 
					  by the Free Software Foundation; either version 2 of the License,
 | 
				
			||||||
 | 
					  or (at your option) any later version.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio 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 Lesser General Public License
 | 
				
			||||||
 | 
					  along with polypaudio; if not, write to the Free Software
 | 
				
			||||||
 | 
					  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
				
			||||||
 | 
					  USA.
 | 
				
			||||||
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <polyp/sample.h>
 | 
				
			||||||
 | 
					#include <polyp/cdecl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \file
 | 
				
			||||||
 | 
					 * Constants and routines for channel mapping handling */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PA_C_DECL_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_INVALID = -1,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_MONO = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_LEFT,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_RIGHT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_FRONT_CENTER,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_FRONT_LEFT = PA_CHANNEL_POSITION_LEFT,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_FRONT_RIGHT = PA_CHANNEL_POSITION_RIGHT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_REAR_CENTER,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_REAR_LEFT,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_REAR_RIGHT,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_LFE,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_LFE,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_SIDE_LEFT,
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_SIDE_RIGHT,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    PA_CHANNEL_POSITION_MAX
 | 
				
			||||||
 | 
					} pa_channel_position_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    pa_channel_position_t map[PA_CHANNELS_MAX];
 | 
				
			||||||
 | 
					} pa_channel_map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init(struct pa_channel_map *m);
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init_mono(struct pa_channel_map *m);
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init_stereo(struct pa_channel_map *m);
 | 
				
			||||||
 | 
					struct pa_channel_map* pa_channel_map_init_auto(struct pa_channel_map *m, int channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char* pa_channel_position_to_string(pa_channel_position_t pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pa_channel_map_equal(struct pa_channel_map *a, struct pa_channel_map *b, int channels)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PA_C_DECL_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -33,16 +33,16 @@
 | 
				
			||||||
#include "subscribe.h"
 | 
					#include "subscribe.h"
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_client *pa_client_new(struct pa_core *core, pa_typeid_t typeid, const char *name) {
 | 
					struct pa_client *pa_client_new(struct pa_core *core, const char *name, const char *driver) {
 | 
				
			||||||
    struct pa_client *c;
 | 
					    struct pa_client *c;
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    assert(core);
 | 
					    assert(core);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c = pa_xmalloc(sizeof(struct pa_client));
 | 
					    c = pa_xmalloc(sizeof(struct pa_client));
 | 
				
			||||||
    c->name = pa_xstrdup(name);
 | 
					    c->name = pa_xstrdup(name);
 | 
				
			||||||
 | 
					    c->driver = pa_xstrdup(driver);
 | 
				
			||||||
    c->owner = NULL;
 | 
					    c->owner = NULL;
 | 
				
			||||||
    c->core = core;
 | 
					    c->core = core;
 | 
				
			||||||
    c->typeid = typeid;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->kill = NULL;
 | 
					    c->kill = NULL;
 | 
				
			||||||
    c->userdata = NULL;
 | 
					    c->userdata = NULL;
 | 
				
			||||||
| 
						 | 
					@ -68,8 +68,8 @@ void pa_client_free(struct pa_client *c) {
 | 
				
			||||||
    pa_log_info(__FILE__": freed %u \"%s\"\n", c->index, c->name);
 | 
					    pa_log_info(__FILE__": freed %u \"%s\"\n", c->index, c->name);
 | 
				
			||||||
    pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
 | 
					    pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
 | 
				
			||||||
    pa_xfree(c->name);
 | 
					    pa_xfree(c->name);
 | 
				
			||||||
 | 
					    pa_xfree(c->driver);
 | 
				
			||||||
    pa_xfree(c);
 | 
					    pa_xfree(c);
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_client_kill(struct pa_client *c) {
 | 
					void pa_client_kill(struct pa_client *c) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,17 +32,16 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_client {
 | 
					struct pa_client {
 | 
				
			||||||
    uint32_t index;
 | 
					    uint32_t index;
 | 
				
			||||||
    pa_typeid_t typeid;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct pa_module *owner;
 | 
					    struct pa_module *owner;
 | 
				
			||||||
    char *name;
 | 
					    char *name, *driver;
 | 
				
			||||||
    struct pa_core *core;
 | 
					    struct pa_core *core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void (*kill)(struct pa_client *c);
 | 
					    void (*kill)(struct pa_client *c);
 | 
				
			||||||
    void *userdata;
 | 
					    void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_client *pa_client_new(struct pa_core *c, pa_typeid_t typeid, const char *name);
 | 
					struct pa_client *pa_client_new(struct pa_core *c, const char *name, const char *driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This function should be called only by the code that created the client */
 | 
					/* This function should be called only by the code that created the client */
 | 
				
			||||||
void pa_client_free(struct pa_client *c);
 | 
					void pa_client_free(struct pa_client *c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,11 +35,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_resampler {
 | 
					struct pa_resampler {
 | 
				
			||||||
    struct pa_sample_spec i_ss, o_ss;
 | 
					    struct pa_sample_spec i_ss, o_ss;
 | 
				
			||||||
 | 
					    struct pa_channel_map i_cm, o_cm;
 | 
				
			||||||
    size_t i_fz, o_fz;
 | 
					    size_t i_fz, o_fz;
 | 
				
			||||||
    struct pa_memblock_stat *memblock_stat;
 | 
					    struct pa_memblock_stat *memblock_stat;
 | 
				
			||||||
    void *impl_data;
 | 
					    void *impl_data;
 | 
				
			||||||
    int channels;
 | 
					    int channels;
 | 
				
			||||||
    enum pa_resample_method resample_method;
 | 
					    pa_resample_method_t resample_method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void (*impl_free)(struct pa_resampler *r);
 | 
					    void (*impl_free)(struct pa_resampler *r);
 | 
				
			||||||
    void (*impl_set_input_rate)(struct pa_resampler *r, uint32_t rate);
 | 
					    void (*impl_set_input_rate)(struct pa_resampler *r, uint32_t rate);
 | 
				
			||||||
| 
						 | 
					@ -62,7 +63,14 @@ struct impl_trivial {
 | 
				
			||||||
static int libsamplerate_init(struct pa_resampler*r);
 | 
					static int libsamplerate_init(struct pa_resampler*r);
 | 
				
			||||||
static int trivial_init(struct pa_resampler*r);
 | 
					static int trivial_init(struct pa_resampler*r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const struct pa_sample_spec *b, struct pa_memblock_stat *s, enum pa_resample_method resample_method) {
 | 
					struct pa_resampler* pa_resampler_new(
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *a,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *am,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *b,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *bm,
 | 
				
			||||||
 | 
					    struct pa_memblock_stat *s,
 | 
				
			||||||
 | 
					    pa_resample_method_t resample_method) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    struct pa_resampler *r = NULL;
 | 
					    struct pa_resampler *r = NULL;
 | 
				
			||||||
    assert(a && b && pa_sample_spec_valid(a) && pa_sample_spec_valid(b) && resample_method != PA_RESAMPLER_INVALID);
 | 
					    assert(a && b && pa_sample_spec_valid(a) && pa_sample_spec_valid(b) && resample_method != PA_RESAMPLER_INVALID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +90,17 @@ struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const stru
 | 
				
			||||||
    r->i_ss = *a;
 | 
					    r->i_ss = *a;
 | 
				
			||||||
    r->o_ss = *b;
 | 
					    r->o_ss = *b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (am)
 | 
				
			||||||
 | 
					        r->i_cm = *am;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (bm)
 | 
				
			||||||
 | 
					        r->o_cm = *bm;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    r->i_fz = pa_frame_size(a);
 | 
					    r->i_fz = pa_frame_size(a);
 | 
				
			||||||
    r->o_fz = pa_frame_size(b);
 | 
					    r->o_fz = pa_frame_size(b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,7 +109,7 @@ struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const stru
 | 
				
			||||||
        r->channels = b->channels;
 | 
					        r->channels = b->channels;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* Choose implementation */
 | 
					    /* Choose implementation */
 | 
				
			||||||
    if (a->channels != b->channels || a->format != b->format || resample_method != PA_RESAMPLER_TRIVIAL) {
 | 
					    if (a->channels != b->channels || a->format != b->format || resample_method != PA_RESAMPLER_TRIVIAL || !pa_channel_map_equal(&r->i_cm, &r->o_cm)) {
 | 
				
			||||||
        /* Use the libsamplerate based resampler for the complicated cases */
 | 
					        /* Use the libsamplerate based resampler for the complicated cases */
 | 
				
			||||||
        if (resample_method == PA_RESAMPLER_TRIVIAL)
 | 
					        if (resample_method == PA_RESAMPLER_TRIVIAL)
 | 
				
			||||||
            r->resample_method = PA_RESAMPLER_SRC_ZERO_ORDER_HOLD;
 | 
					            r->resample_method = PA_RESAMPLER_SRC_ZERO_ORDER_HOLD;
 | 
				
			||||||
| 
						 | 
					@ -141,31 +160,11 @@ size_t pa_resampler_request(struct pa_resampler *r, size_t out_length) {
 | 
				
			||||||
    return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz;
 | 
					    return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum pa_resample_method pa_resampler_get_method(struct pa_resampler *r) {
 | 
					pa_resample_method_t pa_resampler_get_method(struct pa_resampler *r) {
 | 
				
			||||||
    assert(r);
 | 
					    assert(r);
 | 
				
			||||||
    return r->resample_method;
 | 
					    return r->resample_method;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Parse a libsamplrate compatible resampling implementation */
 | 
					 | 
				
			||||||
enum pa_resample_method pa_parse_resample_method(const char *string) {
 | 
					 | 
				
			||||||
    assert(string);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!strcmp(string, "src-sinc-best-quality"))
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_SRC_SINC_BEST_QUALITY;
 | 
					 | 
				
			||||||
    else if (!strcmp(string, "src-sinc-medium-quality"))
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY;
 | 
					 | 
				
			||||||
    else if (!strcmp(string, "src-sinc-fastest"))
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_SRC_SINC_FASTEST;
 | 
					 | 
				
			||||||
    else if (!strcmp(string, "src-zero-order-hold"))
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_SRC_ZERO_ORDER_HOLD;
 | 
					 | 
				
			||||||
    else if (!strcmp(string, "src-linear"))
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_SRC_LINEAR;
 | 
					 | 
				
			||||||
    else if (!strcmp(string, "trivial"))
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_TRIVIAL;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        return PA_RESAMPLER_INVALID;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*** libsamplerate based implementation ***/
 | 
					/*** libsamplerate based implementation ***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void libsamplerate_free(struct pa_resampler *r) {
 | 
					static void libsamplerate_free(struct pa_resampler *r) {
 | 
				
			||||||
| 
						 | 
					@ -181,6 +180,70 @@ static void libsamplerate_free(struct pa_resampler *r) {
 | 
				
			||||||
    pa_xfree(i);
 | 
					    pa_xfree(i);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void calc_map_table(struct pa_resampler *r) {
 | 
				
			||||||
 | 
					    struct impl_libsamplerate *u;
 | 
				
			||||||
 | 
					    unsigned oc;
 | 
				
			||||||
 | 
					    assert(r);
 | 
				
			||||||
 | 
					    assert(r->impl_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u = r->impl_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((u->map_required = (!pa_channel_map_equal(&r->i_cm, r->o_cm) || r->i_ss.channels != r->o_ss.channels))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memset(u->map_table, -1, sizeof(u->map_table));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (oc = 0; oc < r->o_iss.channels; oc++) {
 | 
				
			||||||
 | 
					            unsigned i = 0, ic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (ic = 0; ic < r->i_ss.channels; ic++) {
 | 
				
			||||||
 | 
					                pa_channel_position_t a, b;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                a = r->i_cm.map[ic];
 | 
				
			||||||
 | 
					                b = r->o_cm.map[oc];
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (a == b ||
 | 
				
			||||||
 | 
					                    (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_LEFT) ||
 | 
				
			||||||
 | 
					                    (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_RIGHT) ||
 | 
				
			||||||
 | 
					                    (a == PA_CHANNEL_POSITION_LEFT && b == PA_CHANNEL_POSITION_MONO) ||
 | 
				
			||||||
 | 
					                    (a == PA_CHANNEL_POSITION_RIGHT && b == PA_CHANNEL_POSITION_MONO))
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    u->map_table[oc][i++] = ic;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static float *remap_to_float(struct pa_resampler *r, const struct pa_memchunk *in) {
 | 
				
			||||||
 | 
					    unsigned nsamples;
 | 
				
			||||||
 | 
					    struct impl_libsamplerate *u;
 | 
				
			||||||
 | 
					    assert(r);
 | 
				
			||||||
 | 
					    assert(r->impl_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u = r->impl_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nsamples = in->length / u->i_fz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if () {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (u->i_buf_samples < nsamples)
 | 
				
			||||||
 | 
					            u->i_buf = pa_xrealloc(i->i_buf, sizeof(float) * (i->i_buf_samples = nsamples));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i->to_float32ne_func(ff_ins, (uint8_t*) in->memblock->data+in->index, i_nchannels, i->i_buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void libsamplerate_run(struct pa_resampler *r, const struct pa_memchunk *in, struct pa_memchunk *out) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void libsamplerate_run(struct pa_resampler *r, const struct pa_memchunk *in, struct pa_memchunk *out) {
 | 
					static void libsamplerate_run(struct pa_resampler *r, const struct pa_memchunk *in, struct pa_memchunk *out) {
 | 
				
			||||||
    unsigned i_nchannels, o_nchannels, ins, ons, eff_ins, eff_ons;
 | 
					    unsigned i_nchannels, o_nchannels, ins, ons, eff_ins, eff_ons;
 | 
				
			||||||
    float *cbuf;
 | 
					    float *cbuf;
 | 
				
			||||||
| 
						 | 
					@ -191,7 +254,8 @@ static void libsamplerate_run(struct pa_resampler *r, const struct pa_memchunk *
 | 
				
			||||||
    /* How many input samples? */
 | 
					    /* How many input samples? */
 | 
				
			||||||
    ins = in->length/r->i_fz;
 | 
					    ins = in->length/r->i_fz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*     pa_log("%u / %u = %u\n", in->length, r->i_fz, ins); */
 | 
					
 | 
				
			||||||
 | 
					    /*     pa_log("%u / %u = %u\n", in->length, r->i_fz, ins); */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* How much space for output samples? */
 | 
					    /* How much space for output samples? */
 | 
				
			||||||
    if (i->src_state)
 | 
					    if (i->src_state)
 | 
				
			||||||
| 
						 | 
					@ -395,7 +459,7 @@ static int trivial_init(struct pa_resampler*r) {
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *pa_resample_method_to_string(enum pa_resample_method m) {
 | 
					const char *pa_resample_method_to_string(pa_resample_method_t m) {
 | 
				
			||||||
    static const char * const resample_methods[] = {
 | 
					    static const char * const resample_methods[] = {
 | 
				
			||||||
        "src-sinc-best-quality",
 | 
					        "src-sinc-best-quality",
 | 
				
			||||||
        "src-sinc-medium-quality",
 | 
					        "src-sinc-medium-quality",
 | 
				
			||||||
| 
						 | 
					@ -410,3 +474,23 @@ const char *pa_resample_method_to_string(enum pa_resample_method m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return resample_methods[m];
 | 
					    return resample_methods[m];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_resample_method_t pa_parse_resample_method(const char *string) {
 | 
				
			||||||
 | 
					    assert(string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!strcmp(string, "src-sinc-best-quality"))
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_SRC_SINC_BEST_QUALITY;
 | 
				
			||||||
 | 
					    else if (!strcmp(string, "src-sinc-medium-quality"))
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY;
 | 
				
			||||||
 | 
					    else if (!strcmp(string, "src-sinc-fastest"))
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_SRC_SINC_FASTEST;
 | 
				
			||||||
 | 
					    else if (!strcmp(string, "src-zero-order-hold"))
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_SRC_ZERO_ORDER_HOLD;
 | 
				
			||||||
 | 
					    else if (!strcmp(string, "src-linear"))
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_SRC_LINEAR;
 | 
				
			||||||
 | 
					    else if (!strcmp(string, "trivial"))
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_TRIVIAL;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return PA_RESAMPLER_INVALID;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_resampler;
 | 
					struct pa_resampler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum pa_resample_method {
 | 
					typedef enum {
 | 
				
			||||||
    PA_RESAMPLER_INVALID                 = -1,
 | 
					    PA_RESAMPLER_INVALID                 = -1,
 | 
				
			||||||
    PA_RESAMPLER_SRC_SINC_BEST_QUALITY   = SRC_SINC_BEST_QUALITY,
 | 
					    PA_RESAMPLER_SRC_SINC_BEST_QUALITY   = SRC_SINC_BEST_QUALITY,
 | 
				
			||||||
    PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = SRC_SINC_MEDIUM_QUALITY,
 | 
					    PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = SRC_SINC_MEDIUM_QUALITY,
 | 
				
			||||||
| 
						 | 
					@ -39,9 +39,16 @@ enum pa_resample_method {
 | 
				
			||||||
    PA_RESAMPLER_SRC_LINEAR              = SRC_LINEAR,
 | 
					    PA_RESAMPLER_SRC_LINEAR              = SRC_LINEAR,
 | 
				
			||||||
    PA_RESAMPLER_TRIVIAL,
 | 
					    PA_RESAMPLER_TRIVIAL,
 | 
				
			||||||
    PA_RESAMPLER_MAX
 | 
					    PA_RESAMPLER_MAX
 | 
				
			||||||
};
 | 
					} pa_resample_method_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_resampler* pa_resampler_new(
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *a,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *am,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *b,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *bm,
 | 
				
			||||||
 | 
					    struct pa_memblock_stat *s,
 | 
				
			||||||
 | 
					    pa_resample_method_t resample_method);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_resampler* pa_resampler_new(const struct pa_sample_spec *a, const struct pa_sample_spec *b, struct pa_memblock_stat *s, int resample_method);
 | 
					 | 
				
			||||||
void pa_resampler_free(struct pa_resampler *r);
 | 
					void pa_resampler_free(struct pa_resampler *r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Returns the size of an input memory block which is required to return the specified amount of output data */
 | 
					/* Returns the size of an input memory block which is required to return the specified amount of output data */
 | 
				
			||||||
| 
						 | 
					@ -54,12 +61,12 @@ void pa_resampler_run(struct pa_resampler *r, const struct pa_memchunk *in, stru
 | 
				
			||||||
void pa_resampler_set_input_rate(struct pa_resampler *r, uint32_t rate);
 | 
					void pa_resampler_set_input_rate(struct pa_resampler *r, uint32_t rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Return the resampling method of the resampler object */
 | 
					/* Return the resampling method of the resampler object */
 | 
				
			||||||
enum pa_resample_method pa_resampler_get_method(struct pa_resampler *r);
 | 
					pa_resample_method_t pa_resampler_get_method(struct pa_resampler *r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Try to parse the resampler method */
 | 
					/* Try to parse the resampler method */
 | 
				
			||||||
enum pa_resample_method pa_parse_resample_method(const char *string);
 | 
					pa_resample_method_t pa_parse_resample_method(const char *string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* return a human readable string for the specified resampling method. Inverse of pa_parse_resample_method() */
 | 
					/* return a human readable string for the specified resampling method. Inverse of pa_parse_resample_method() */
 | 
				
			||||||
const char *pa_resample_method_to_string(enum pa_resample_method m);
 | 
					const char *pa_resample_method_to_string(pa_resample_method_t m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,30 +65,37 @@ void pa_silence_memory(void *p, size_t length, const struct pa_sample_spec *spec
 | 
				
			||||||
    memset(p, c, length);
 | 
					    memset(p, c, length);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, size_t length, const struct pa_sample_spec *spec, pa_volume_t volume) {
 | 
					size_t pa_mix(struct pa_mix_info streams[],
 | 
				
			||||||
    assert(channels && data && length && spec);
 | 
					              unsigned nstreams,
 | 
				
			||||||
 | 
					              void *data,
 | 
				
			||||||
 | 
					              size_t length,
 | 
				
			||||||
 | 
					              const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					              const struct pa_cvolume *volume) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    assert(streams && data && length && spec);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (spec->format == PA_SAMPLE_S16NE) {
 | 
					    if (spec->format == PA_SAMPLE_S16NE) {
 | 
				
			||||||
        size_t d;
 | 
					        size_t d;
 | 
				
			||||||
 | 
					        unsigned channel = 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (d = 0;; d += sizeof(int16_t)) {
 | 
					        for (d = 0;; d += sizeof(int16_t)) {
 | 
				
			||||||
            unsigned c;
 | 
					            unsigned i;
 | 
				
			||||||
            int32_t sum = 0;
 | 
					            int32_t sum = 0;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (d >= length)
 | 
					            if (d >= length)
 | 
				
			||||||
                return d;
 | 
					                return d;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            for (c = 0; c < nchannels; c++) {
 | 
					            for (i = 0; i < nstreams; i++) {
 | 
				
			||||||
                int32_t v;
 | 
					                int32_t v;
 | 
				
			||||||
                pa_volume_t cvolume = channels[c].volume;
 | 
					                pa_volume_t cvolume = streams[i].volume.values[channel];
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (d >= channels[c].chunk.length)
 | 
					                if (d >= streams[i].chunk.length)
 | 
				
			||||||
                    return d;
 | 
					                    return d;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (cvolume == PA_VOLUME_MUTED)
 | 
					                if (cvolume == PA_VOLUME_MUTED)
 | 
				
			||||||
                    v = 0;
 | 
					                    v = 0;
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    v = *((int16_t*) ((uint8_t*) channels[c].chunk.memblock->data + channels[c].chunk.index + d));
 | 
					                    v = *((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d));
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (cvolume != PA_VOLUME_NORM) {
 | 
					                    if (cvolume != PA_VOLUME_NORM) {
 | 
				
			||||||
                        v *= cvolume;
 | 
					                        v *= cvolume;
 | 
				
			||||||
| 
						 | 
					@ -111,28 +118,32 @@ size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, siz
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            *((int16_t*) data) = sum;
 | 
					            *((int16_t*) data) = sum;
 | 
				
			||||||
            data = (uint8_t*) data + sizeof(int16_t);
 | 
					            data = (uint8_t*) data + sizeof(int16_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (++channel >= spec->channels)
 | 
				
			||||||
 | 
					                channel = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (spec->format == PA_SAMPLE_U8) {
 | 
					    } else if (spec->format == PA_SAMPLE_U8) {
 | 
				
			||||||
        size_t d;
 | 
					        size_t d;
 | 
				
			||||||
 | 
					        unsigned channel = 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (d = 0;; d ++) {
 | 
					        for (d = 0;; d ++) {
 | 
				
			||||||
            int32_t sum = 0;
 | 
					            int32_t sum = 0;
 | 
				
			||||||
            unsigned c;
 | 
					            unsigned i;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (d >= length)
 | 
					            if (d >= length)
 | 
				
			||||||
                return d;
 | 
					                return d;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            for (c = 0; c < nchannels; c++) {
 | 
					            for (i = 0; i < nstreams; i++) {
 | 
				
			||||||
                int32_t v;
 | 
					                int32_t v;
 | 
				
			||||||
                pa_volume_t cvolume = channels[c].volume;
 | 
					                pa_volume_t cvolume = streams[i].volume.values[channel];
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (d >= channels[c].chunk.length)
 | 
					                if (d >= streams[i].chunk.length)
 | 
				
			||||||
                    return d;
 | 
					                    return d;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (cvolume == PA_VOLUME_MUTED)
 | 
					                if (cvolume == PA_VOLUME_MUTED)
 | 
				
			||||||
                    v = 0;
 | 
					                    v = 0;
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    v = (int32_t) *((uint8_t*) channels[c].chunk.memblock->data + channels[c].chunk.index + d) - 0x80;
 | 
					                    v = (int32_t) *((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d) - 0x80;
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (cvolume != PA_VOLUME_NORM) {
 | 
					                    if (cvolume != PA_VOLUME_NORM) {
 | 
				
			||||||
                        v *= cvolume;
 | 
					                        v *= cvolume;
 | 
				
			||||||
| 
						 | 
					@ -155,29 +166,33 @@ size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, siz
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            *((uint8_t*) data) = (uint8_t) (sum + 0x80);
 | 
					            *((uint8_t*) data) = (uint8_t) (sum + 0x80);
 | 
				
			||||||
            data = (uint8_t*) data + 1;
 | 
					            data = (uint8_t*) data + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (++channel >= spec->channels)
 | 
				
			||||||
 | 
					                channel = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    } else if (spec->format == PA_SAMPLE_FLOAT32NE) {
 | 
					    } else if (spec->format == PA_SAMPLE_FLOAT32NE) {
 | 
				
			||||||
        size_t d;
 | 
					        size_t d;
 | 
				
			||||||
 | 
					        unsigned channel = 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (d = 0;; d += sizeof(float)) {
 | 
					        for (d = 0;; d += sizeof(float)) {
 | 
				
			||||||
            float_t sum = 0;
 | 
					            float_t sum = 0;
 | 
				
			||||||
            unsigned c;
 | 
					            unsigned i;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (d >= length)
 | 
					            if (d >= length)
 | 
				
			||||||
                return d;
 | 
					                return d;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            for (c = 0; c < nchannels; c++) {
 | 
					            for (i = 0; i < nstreams; i++) {
 | 
				
			||||||
                float v;
 | 
					                float v;
 | 
				
			||||||
                pa_volume_t cvolume = channels[c].volume;
 | 
					                pa_volume_t cvolume = streams[i].volume.values[channel];
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (d >= channels[c].chunk.length)
 | 
					                if (d >= streams[i].chunk.length)
 | 
				
			||||||
                    return d;
 | 
					                    return d;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (cvolume == PA_VOLUME_MUTED)
 | 
					                if (cvolume == PA_VOLUME_MUTED)
 | 
				
			||||||
                    v = 0;
 | 
					                    v = 0;
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    v = *((float*) ((uint8_t*) channels[c].chunk.memblock->data + channels[c].chunk.index + d));
 | 
					                    v = *((float*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d));
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (cvolume != PA_VOLUME_NORM)
 | 
					                    if (cvolume != PA_VOLUME_NORM)
 | 
				
			||||||
                        v = v*cvolume/PA_VOLUME_NORM;
 | 
					                        v = v*cvolume/PA_VOLUME_NORM;
 | 
				
			||||||
| 
						 | 
					@ -196,6 +211,9 @@ size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, siz
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            *((float*) data) = sum;
 | 
					            *((float*) data) = sum;
 | 
				
			||||||
            data = (uint8_t*) data + sizeof(float);
 | 
					            data = (uint8_t*) data + sizeof(float);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (++channel >= spec->channels)
 | 
				
			||||||
 | 
					                channel = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        abort();
 | 
					        abort();
 | 
				
			||||||
| 
						 | 
					@ -203,13 +221,14 @@ size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, siz
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec, pa_volume_t volume) {
 | 
					void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec, const struct pa_cvolume *volume) {
 | 
				
			||||||
    assert(c && spec && (c->length % pa_frame_size(spec) == 0));
 | 
					    assert(c && spec && (c->length % pa_frame_size(spec) == 0));
 | 
				
			||||||
 | 
					    assert(volume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (volume == PA_VOLUME_NORM)
 | 
					    if (pa_cvolume_channels_equal_to(volume, spec->channels, PA_VOLUME_NORM))
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (volume == PA_VOLUME_MUTED) {
 | 
					    if (pa_cvolume_channels_equal_to(volume, spec->channels, PA_VOLUME_MUTED)) {
 | 
				
			||||||
        pa_silence_memchunk(c, spec);
 | 
					        pa_silence_memchunk(c, spec);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -217,26 +236,31 @@ void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec,
 | 
				
			||||||
    if (spec->format == PA_SAMPLE_S16NE) {
 | 
					    if (spec->format == PA_SAMPLE_S16NE) {
 | 
				
			||||||
        int16_t *d;
 | 
					        int16_t *d;
 | 
				
			||||||
        size_t n;
 | 
					        size_t n;
 | 
				
			||||||
 | 
					        unsigned c = 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) {
 | 
					        for (d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) {
 | 
				
			||||||
            int32_t t = (int32_t)(*d);
 | 
					            int32_t t = (int32_t)(*d);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            t *= volume;
 | 
					            t *= volume->values[c];
 | 
				
			||||||
            t /= PA_VOLUME_NORM;
 | 
					            t /= PA_VOLUME_NORM;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (t < -0x8000) t = -0x8000;
 | 
					            if (t < -0x8000) t = -0x8000;
 | 
				
			||||||
            if (t > 0x7FFF) t = 0x7FFF;
 | 
					            if (t > 0x7FFF) t = 0x7FFF;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            *d = (int16_t) t;
 | 
					            *d = (int16_t) t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (++c >= spec->channels)
 | 
				
			||||||
 | 
					                c = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (spec->format == PA_SAMPLE_U8) {
 | 
					    } else if (spec->format == PA_SAMPLE_U8) {
 | 
				
			||||||
        uint8_t *d;
 | 
					        uint8_t *d;
 | 
				
			||||||
        size_t n;
 | 
					        size_t n;
 | 
				
			||||||
 | 
					        unsigned c = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (d = (uint8_t*) c->memblock->data + c->index, n = c->length; n > 0; d++, n--) {
 | 
					        for (d = (uint8_t*) c->memblock->data + c->index, n = c->length; n > 0; d++, n--) {
 | 
				
			||||||
            int32_t t = (int32_t) *d - 0x80;
 | 
					            int32_t t = (int32_t) *d - 0x80;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            t *= volume;
 | 
					            t *= volume->values[c];
 | 
				
			||||||
            t /= PA_VOLUME_NORM;
 | 
					            t /= PA_VOLUME_NORM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (t < -0x80) t = -0x80;
 | 
					            if (t < -0x80) t = -0x80;
 | 
				
			||||||
| 
						 | 
					@ -244,21 +268,27 @@ void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            *d = (uint8_t) (t + 0x80);
 | 
					            *d = (uint8_t) (t + 0x80);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            if (++c >= spec->channels)
 | 
				
			||||||
 | 
					                c = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (spec->format == PA_SAMPLE_FLOAT32NE) {
 | 
					    } else if (spec->format == PA_SAMPLE_FLOAT32NE) {
 | 
				
			||||||
        float *d;
 | 
					        float *d;
 | 
				
			||||||
        size_t n;
 | 
					        size_t n;
 | 
				
			||||||
 | 
					        unsigned c = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (d = (float*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(float); n > 0; d++, n--) {
 | 
					        for (d = (float*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(float); n > 0; d++, n--) {
 | 
				
			||||||
            float t = *d;
 | 
					            float t = *d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            t *= volume;
 | 
					            t *= volume->values[c];
 | 
				
			||||||
            t /= PA_VOLUME_NORM;
 | 
					            t /= PA_VOLUME_NORM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (t < -1) t = -1;
 | 
					            if (t < -1) t = -1;
 | 
				
			||||||
            if (t > 1) t = 1;
 | 
					            if (t > 1) t = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            *d = t;
 | 
					            *d = t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (++c >= spec->channels)
 | 
				
			||||||
 | 
					                c = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,12 +33,19 @@ void pa_silence_memory(void *p, size_t length, const struct pa_sample_spec *spec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_mix_info {
 | 
					struct pa_mix_info {
 | 
				
			||||||
    struct pa_memchunk chunk;
 | 
					    struct pa_memchunk chunk;
 | 
				
			||||||
    pa_volume_t volume;
 | 
					    struct pa_cvolume cvolume;
 | 
				
			||||||
    void *userdata;
 | 
					    void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, size_t length, const struct pa_sample_spec *spec, pa_volume_t volume);
 | 
					size_t pa_mix(const struct pa_mix_info channels[],
 | 
				
			||||||
 | 
					              unsigned nchannels,
 | 
				
			||||||
 | 
					              void *data,
 | 
				
			||||||
 | 
					              size_t length,
 | 
				
			||||||
 | 
					              const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					              const struct pa_cvolume *volume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec, pa_volume_t volume);
 | 
					void pa_volume_memchunk(struct pa_memchunk*c,
 | 
				
			||||||
 | 
					                        const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					                        const struct pa_cvolume *volume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,10 +69,11 @@ pa_usec_t pa_bytes_to_usec(uint64_t length, const struct pa_sample_spec *spec) {
 | 
				
			||||||
int pa_sample_spec_valid(const struct pa_sample_spec *spec) {
 | 
					int pa_sample_spec_valid(const struct pa_sample_spec *spec) {
 | 
				
			||||||
    assert(spec);
 | 
					    assert(spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (spec->rate <= 0 || spec->channels <= 0)
 | 
					    if (spec->rate <= 0 ||
 | 
				
			||||||
        return 0;
 | 
					        spec->channels <= 0 ||
 | 
				
			||||||
 | 
					        spec->channels >= PA_CHANNELS_MAX ||
 | 
				
			||||||
    if (spec->format >= PA_SAMPLE_MAX || spec->format < 0)
 | 
					        spec->format >= PA_SAMPLE_MAX ||
 | 
				
			||||||
 | 
					        spec->format < 0)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
| 
						 | 
					@ -86,13 +87,13 @@ int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *pa_sample_format_to_string(enum pa_sample_format f) {
 | 
					const char *pa_sample_format_to_string(enum pa_sample_format f) {
 | 
				
			||||||
    static const char* const table[]= {
 | 
					    static const char* const table[]= {
 | 
				
			||||||
        [PA_SAMPLE_U8] = "U8",
 | 
					        [PA_SAMPLE_U8] = "u8",
 | 
				
			||||||
        [PA_SAMPLE_ALAW] = "ALAW",
 | 
					        [PA_SAMPLE_ALAW] = "aLaw",
 | 
				
			||||||
        [PA_SAMPLE_ULAW] = "ULAW",
 | 
					        [PA_SAMPLE_ULAW] = "uLaw",
 | 
				
			||||||
        [PA_SAMPLE_S16LE] = "S16LE",
 | 
					        [PA_SAMPLE_S16LE] = "s16le",
 | 
				
			||||||
        [PA_SAMPLE_S16BE] = "S16BE",
 | 
					        [PA_SAMPLE_S16BE] = "s16be",
 | 
				
			||||||
        [PA_SAMPLE_FLOAT32LE] = "FLOAT32LE",
 | 
					        [PA_SAMPLE_FLOAT32LE] = "float32le",
 | 
				
			||||||
        [PA_SAMPLE_FLOAT32BE] = "FLOAT32BE",
 | 
					        [PA_SAMPLE_FLOAT32BE] = "float32be",
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (f >= PA_SAMPLE_MAX)
 | 
					    if (f >= PA_SAMPLE_MAX)
 | 
				
			||||||
| 
						 | 
					@ -112,43 +113,6 @@ char *pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spe
 | 
				
			||||||
    return s;
 | 
					    return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_volume_t pa_volume_multiply(pa_volume_t a, pa_volume_t b) {
 | 
					 | 
				
			||||||
    uint64_t p = a;
 | 
					 | 
				
			||||||
    p *= b;
 | 
					 | 
				
			||||||
    p /= PA_VOLUME_NORM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (pa_volume_t) p;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pa_volume_t pa_volume_from_dB(double f) {
 | 
					 | 
				
			||||||
    if (f <= PA_DECIBEL_MININFTY)
 | 
					 | 
				
			||||||
        return PA_VOLUME_MUTED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (pa_volume_t) (pow(10, f/20)*PA_VOLUME_NORM);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
double pa_volume_to_dB(pa_volume_t v) {
 | 
					 | 
				
			||||||
    if (v == PA_VOLUME_MUTED)
 | 
					 | 
				
			||||||
        return PA_DECIBEL_MININFTY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 20*log10((double) v/PA_VOLUME_NORM);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define USER_DECIBEL_RANGE 30
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
double pa_volume_to_user(pa_volume_t v) {
 | 
					 | 
				
			||||||
    double dB = pa_volume_to_dB(v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return dB < -USER_DECIBEL_RANGE ? 0 : dB/USER_DECIBEL_RANGE+1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pa_volume_t pa_volume_from_user(double v) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (v <= 0)
 | 
					 | 
				
			||||||
        return PA_VOLUME_MUTED;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    return pa_volume_from_dB((v-1)*USER_DECIBEL_RANGE);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_bytes_snprint(char *s, size_t l, unsigned v) {
 | 
					void pa_bytes_snprint(char *s, size_t l, unsigned v) {
 | 
				
			||||||
    if (v >= ((unsigned) 1024)*1024*1024)
 | 
					    if (v >= ((unsigned) 1024)*1024*1024)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,8 +33,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PA_C_DECL_BEGIN
 | 
					PA_C_DECL_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Maximum allowed channels */
 | 
				
			||||||
 | 
					#define PA_CHANNELS_MAX 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Sample format */
 | 
					/** Sample format */
 | 
				
			||||||
enum pa_sample_format {
 | 
					typedef enum {
 | 
				
			||||||
    PA_SAMPLE_U8,              /**< Unsigned 8 Bit PCM */
 | 
					    PA_SAMPLE_U8,              /**< Unsigned 8 Bit PCM */
 | 
				
			||||||
    PA_SAMPLE_ALAW,            /**< 8 Bit a-Law */
 | 
					    PA_SAMPLE_ALAW,            /**< 8 Bit a-Law */
 | 
				
			||||||
    PA_SAMPLE_ULAW,            /**< 8 Bit mu-Law */
 | 
					    PA_SAMPLE_ULAW,            /**< 8 Bit mu-Law */
 | 
				
			||||||
| 
						 | 
					@ -44,7 +47,7 @@ enum pa_sample_format {
 | 
				
			||||||
    PA_SAMPLE_FLOAT32BE,       /**< 32 Bit IEEE floating point, big endian, range -1..1 */
 | 
					    PA_SAMPLE_FLOAT32BE,       /**< 32 Bit IEEE floating point, big endian, range -1..1 */
 | 
				
			||||||
    PA_SAMPLE_MAX,             /**< Upper limit of valid sample types */
 | 
					    PA_SAMPLE_MAX,             /**< Upper limit of valid sample types */
 | 
				
			||||||
    PA_SAMPLE_INVALID = -1     /**< An invalid value */
 | 
					    PA_SAMPLE_INVALID = -1     /**< An invalid value */
 | 
				
			||||||
};
 | 
					} pa_sample_format_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WORDS_BIGENDIAN
 | 
					#ifdef WORDS_BIGENDIAN
 | 
				
			||||||
/** Signed 16 Bit PCM, native endian */
 | 
					/** Signed 16 Bit PCM, native endian */
 | 
				
			||||||
| 
						 | 
					@ -63,7 +66,7 @@ enum pa_sample_format {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** A sample format and attribute specification */
 | 
					/** A sample format and attribute specification */
 | 
				
			||||||
struct pa_sample_spec {
 | 
					struct pa_sample_spec {
 | 
				
			||||||
    enum pa_sample_format format;  /**< The sample format */
 | 
					    pa_sample_format_t format;     /**< The sample format */
 | 
				
			||||||
    uint32_t rate;                 /**< The sample rate. (e.g. 44100) */
 | 
					    uint32_t rate;                 /**< The sample rate. (e.g. 44100) */
 | 
				
			||||||
    uint8_t channels;              /**< Audio channels. (1 for mono, 2 for stereo, ...) */
 | 
					    uint8_t channels;              /**< Audio channels. (1 for mono, 2 for stereo, ...) */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -87,7 +90,10 @@ int pa_sample_spec_valid(const struct pa_sample_spec *spec);
 | 
				
			||||||
int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_spec*b);
 | 
					int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_spec*b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Return a descriptive string for the specified sample format. \since 0.8 */
 | 
					/* Return a descriptive string for the specified sample format. \since 0.8 */
 | 
				
			||||||
const char *pa_sample_format_to_string(enum pa_sample_format f);
 | 
					const char *pa_sample_format_to_string(pa_sample_format_t f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Parse a sample format text. Inverse of pa_sample_format_to_string() */
 | 
				
			||||||
 | 
					pa_sample_format_t pa_parse_sample_format(const char *format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Maximum required string length for pa_sample_spec_snprint() */
 | 
					/** Maximum required string length for pa_sample_spec_snprint() */
 | 
				
			||||||
#define PA_SAMPLE_SPEC_SNPRINT_MAX 32
 | 
					#define PA_SAMPLE_SPEC_SNPRINT_MAX 32
 | 
				
			||||||
| 
						 | 
					@ -95,43 +101,9 @@ const char *pa_sample_format_to_string(enum pa_sample_format f);
 | 
				
			||||||
/** Pretty print a sample type specification to a string */
 | 
					/** Pretty print a sample type specification to a string */
 | 
				
			||||||
char* pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec);
 | 
					char* pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Volume specification: 0: silence; < 256: diminished volume; 256: normal volume; > 256 amplified volume */
 | 
					 | 
				
			||||||
typedef uint32_t pa_volume_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Normal volume (100%) */
 | 
					 | 
				
			||||||
#define PA_VOLUME_NORM (0x100)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Muted volume (0%) */
 | 
					 | 
				
			||||||
#define PA_VOLUME_MUTED (0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. */
 | 
					 | 
				
			||||||
pa_volume_t pa_volume_multiply(pa_volume_t a, pa_volume_t b);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Convert volume from decibel to linear level. \since 0.4 */
 | 
					 | 
				
			||||||
pa_volume_t pa_volume_from_dB(double f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Convert volume from linear level to decibel.  \since 0.4 */
 | 
					 | 
				
			||||||
double pa_volume_to_dB(pa_volume_t v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Convert volume to scaled value understandable by the user (between 0 and 1). \since 0.6 */
 | 
					 | 
				
			||||||
double pa_volume_to_user(pa_volume_t v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Convert user volume to polypaudio volume. \since 0.6 */
 | 
					 | 
				
			||||||
pa_volume_t pa_volume_from_user(double v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef INFINITY
 | 
					 | 
				
			||||||
#define PA_DECIBEL_MININFTY (-INFINITY)
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
/** This value is used as minus infinity when using pa_volume_{to,from}_dB(). \since 0.4 */
 | 
					 | 
				
			||||||
#define PA_DECIBEL_MININFTY (-200)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Pretty print a byte size value. (i.e. "2.5 MB") */
 | 
					/** Pretty print a byte size value. (i.e. "2.5 MB") */
 | 
				
			||||||
void pa_bytes_snprint(char *s, size_t l, unsigned v);
 | 
					void pa_bytes_snprint(char *s, size_t l, unsigned v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Parse a sample format text. Inverse of pa_sample_format_to_string() */
 | 
					 | 
				
			||||||
enum pa_sample_format pa_parse_sample_format(const char *format);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PA_C_DECL_END
 | 
					PA_C_DECL_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,12 +36,23 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CONVERT_BUFFER_LENGTH 4096
 | 
					#define CONVERT_BUFFER_LENGTH 4096
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, pa_typeid_t typeid, const char *name, const struct pa_sample_spec *spec, int variable_rate, int resample_method) {
 | 
					struct pa_sink_input* pa_sink_input_new(
 | 
				
			||||||
 | 
					    struct pa_sink *s,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map,
 | 
				
			||||||
 | 
					    int variable_rate,
 | 
				
			||||||
 | 
					    int resample_method) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    struct pa_sink_input *i;
 | 
					    struct pa_sink_input *i;
 | 
				
			||||||
    struct pa_resampler *resampler = NULL;
 | 
					    struct pa_resampler *resampler = NULL;
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    char st[256];
 | 
					    char st[256];
 | 
				
			||||||
    assert(s && spec && s->state == PA_SINK_RUNNING);
 | 
					
 | 
				
			||||||
 | 
					    assert(s);
 | 
				
			||||||
 | 
					    assert(spec);
 | 
				
			||||||
 | 
					    assert(s->state == PA_SINK_RUNNING);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_idxset_ncontents(s->inputs) >= PA_MAX_INPUTS_PER_SINK) {
 | 
					    if (pa_idxset_ncontents(s->inputs) >= PA_MAX_INPUTS_PER_SINK) {
 | 
				
			||||||
        pa_log(__FILE__": Failed to create sink input: too many inputs per sink.\n");
 | 
					        pa_log(__FILE__": Failed to create sink input: too many inputs per sink.\n");
 | 
				
			||||||
| 
						 | 
					@ -52,18 +63,23 @@ struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, pa_typeid_t typeid, c
 | 
				
			||||||
        resample_method = s->core->resample_method;
 | 
					        resample_method = s->core->resample_method;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec))
 | 
					    if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec))
 | 
				
			||||||
        if (!(resampler = pa_resampler_new(spec, &s->sample_spec, s->core->memblock_stat, resample_method)))
 | 
					        if (!(resampler = pa_resampler_new(spec, map, &s->sample_spec, &s->channel_map, s->core->memblock_stat, resample_method)))
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    i = pa_xmalloc(sizeof(struct pa_sink_input));
 | 
					    i = pa_xmalloc(sizeof(struct pa_sink_input));
 | 
				
			||||||
    i->ref = 1;
 | 
					    i->ref = 1;
 | 
				
			||||||
    i->state = PA_SINK_INPUT_RUNNING;
 | 
					    i->state = PA_SINK_INPUT_RUNNING;
 | 
				
			||||||
    i->name = pa_xstrdup(name);
 | 
					    i->name = pa_xstrdup(name);
 | 
				
			||||||
    i->typeid = typeid;
 | 
					    i->driver = pa_xstrdup(driver);
 | 
				
			||||||
    i->client = NULL;
 | 
					    i->client = NULL;
 | 
				
			||||||
    i->owner = NULL;
 | 
					    i->owner = NULL;
 | 
				
			||||||
    i->sink = s;
 | 
					    i->sink = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i->sample_spec = *spec;
 | 
					    i->sample_spec = *spec;
 | 
				
			||||||
 | 
					    if (map)
 | 
				
			||||||
 | 
					        i->channel_map = *map;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        pa_channel_map_init_auto(&i->channel_map, spec->channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i->peek = NULL;
 | 
					    i->peek = NULL;
 | 
				
			||||||
    i->drop = NULL;
 | 
					    i->drop = NULL;
 | 
				
			||||||
| 
						 | 
					@ -72,7 +88,7 @@ struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, pa_typeid_t typeid, c
 | 
				
			||||||
    i->userdata = NULL;
 | 
					    i->userdata = NULL;
 | 
				
			||||||
    i->underrun = NULL;
 | 
					    i->underrun = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i->volume = PA_VOLUME_NORM;
 | 
					    pa_cvolume_reset(&i->volume);
 | 
				
			||||||
    i->playing = 0;
 | 
					    i->playing = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i->resampled_chunk.memblock = NULL;
 | 
					    i->resampled_chunk.memblock = NULL;
 | 
				
			||||||
| 
						 | 
					@ -124,6 +140,7 @@ static void sink_input_free(struct pa_sink_input* i) {
 | 
				
			||||||
        pa_resampler_free(i->resampler);
 | 
					        pa_resampler_free(i->resampler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_xfree(i->name);
 | 
					    pa_xfree(i->name);
 | 
				
			||||||
 | 
					    pa_xfree(i->driver);
 | 
				
			||||||
    pa_xfree(i);
 | 
					    pa_xfree(i);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -234,15 +251,22 @@ void pa_sink_input_drop(struct pa_sink_input *i, const struct pa_memchunk *chunk
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_input_set_volume(struct pa_sink_input *i, pa_volume_t volume) {
 | 
					void pa_sink_input_set_volume(struct pa_sink_input *i, const struct pa_cvolume *volume) {
 | 
				
			||||||
    assert(i && i->sink && i->sink->core && i->ref >= 1);
 | 
					    assert(i && i->sink && i->sink->core && i->ref >= 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (i->volume != volume) {
 | 
					    if (!pa_cvolume_equal(&i->volume, volume)) {
 | 
				
			||||||
        i->volume = volume;
 | 
					        i->volume = *volume;
 | 
				
			||||||
        pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
 | 
					        pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct pa_cvolume * pa_sink_input_get_volume(struct pa_sink_input *i) {
 | 
				
			||||||
 | 
					    assert(i);
 | 
				
			||||||
 | 
					    assert(i->ref >= 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return &i->volume;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_input_cork(struct pa_sink_input *i, int b) {
 | 
					void pa_sink_input_cork(struct pa_sink_input *i, int b) {
 | 
				
			||||||
    int n;
 | 
					    int n;
 | 
				
			||||||
    assert(i && i->ref >= 1);
 | 
					    assert(i && i->ref >= 1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,25 +31,25 @@
 | 
				
			||||||
#include "module.h"
 | 
					#include "module.h"
 | 
				
			||||||
#include "client.h"
 | 
					#include "client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum pa_sink_input_state {
 | 
					typedef enum {
 | 
				
			||||||
    PA_SINK_INPUT_RUNNING,
 | 
					    PA_SINK_INPUT_RUNNING,
 | 
				
			||||||
    PA_SINK_INPUT_CORKED,
 | 
					    PA_SINK_INPUT_CORKED,
 | 
				
			||||||
    PA_SINK_INPUT_DISCONNECTED
 | 
					    PA_SINK_INPUT_DISCONNECTED
 | 
				
			||||||
};
 | 
					} pa_sink_input_state_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_sink_input {
 | 
					struct pa_sink_input {
 | 
				
			||||||
    int ref;
 | 
					    int ref;
 | 
				
			||||||
    enum pa_sink_input_state state;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint32_t index;
 | 
					    uint32_t index;
 | 
				
			||||||
    pa_typeid_t typeid;
 | 
					    pa_sink_input_state_t state;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    char *name;
 | 
					    char *name, *driver;
 | 
				
			||||||
    struct pa_module *owner;
 | 
					    struct pa_module *owner;
 | 
				
			||||||
    struct pa_client *client;
 | 
					    struct pa_client *client;
 | 
				
			||||||
    struct pa_sink *sink;
 | 
					    struct pa_sink *sink;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    struct pa_sample_spec sample_spec;
 | 
					    struct pa_sample_spec sample_spec;
 | 
				
			||||||
    uint32_t volume;
 | 
					    struct pa_channel_map channel_map;
 | 
				
			||||||
 | 
					    struct pa_cvolume volume;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int (*peek) (struct pa_sink_input *i, struct pa_memchunk *chunk);
 | 
					    int (*peek) (struct pa_sink_input *i, struct pa_memchunk *chunk);
 | 
				
			||||||
    void (*drop) (struct pa_sink_input *i, const struct pa_memchunk *chunk, size_t length);
 | 
					    void (*drop) (struct pa_sink_input *i, const struct pa_memchunk *chunk, size_t length);
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,15 @@ struct pa_sink_input {
 | 
				
			||||||
    struct pa_resampler *resampler;
 | 
					    struct pa_resampler *resampler;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, pa_typeid_t typeid, const char *name, const struct pa_sample_spec *spec, int variable_rate, int resample_method);
 | 
					struct pa_sink_input* pa_sink_input_new(
 | 
				
			||||||
 | 
					    struct pa_sink *s,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map,
 | 
				
			||||||
 | 
					    int variable_rate,
 | 
				
			||||||
 | 
					    int resample_method);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_input_unref(struct pa_sink_input* i);
 | 
					void pa_sink_input_unref(struct pa_sink_input* i);
 | 
				
			||||||
struct pa_sink_input* pa_sink_input_ref(struct pa_sink_input* i);
 | 
					struct pa_sink_input* pa_sink_input_ref(struct pa_sink_input* i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,7 +88,8 @@ pa_usec_t pa_sink_input_get_latency(struct pa_sink_input *i);
 | 
				
			||||||
int pa_sink_input_peek(struct pa_sink_input *i, struct pa_memchunk *chunk);
 | 
					int pa_sink_input_peek(struct pa_sink_input *i, struct pa_memchunk *chunk);
 | 
				
			||||||
void pa_sink_input_drop(struct pa_sink_input *i, const struct pa_memchunk *chunk, size_t length);
 | 
					void pa_sink_input_drop(struct pa_sink_input *i, const struct pa_memchunk *chunk, size_t length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_input_set_volume(struct pa_sink_input *i, pa_volume_t volume);
 | 
					void pa_sink_input_set_volume(struct pa_sink_input *i, const struct pa_cvolume *volume);
 | 
				
			||||||
 | 
					const struct pa_cvolume *volume pa_sink_input_get_volume(struct pa_sink_input *i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_input_cork(struct pa_sink_input *i, int b);
 | 
					void pa_sink_input_cork(struct pa_sink_input *i, int b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										79
									
								
								polyp/sink.c
									
										
									
									
									
								
							
							
						
						
									
										79
									
								
								polyp/sink.c
									
										
									
									
									
								
							| 
						 | 
					@ -39,12 +39,23 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_MIX_CHANNELS 32
 | 
					#define MAX_MIX_CHANNELS 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_sink* pa_sink_new(struct pa_core *core, pa_typeid_t typeid, const char *name, int fail, const struct pa_sample_spec *spec) {
 | 
					struct pa_sink* pa_sink_new(
 | 
				
			||||||
 | 
					    struct pa_core *core,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    int fail,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    struct pa_sink *s;
 | 
					    struct pa_sink *s;
 | 
				
			||||||
    char *n = NULL;
 | 
					    char *n = NULL;
 | 
				
			||||||
    char st[256];
 | 
					    char st[256];
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    assert(core && name && *name && spec);
 | 
					
 | 
				
			||||||
 | 
					    assert(core);
 | 
				
			||||||
 | 
					    assert(name);
 | 
				
			||||||
 | 
					    assert(*name);
 | 
				
			||||||
 | 
					    assert(spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s = pa_xmalloc(sizeof(struct pa_sink));
 | 
					    s = pa_xmalloc(sizeof(struct pa_sink));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,31 +64,41 @@ struct pa_sink* pa_sink_new(struct pa_core *core, pa_typeid_t typeid, const char
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->ref = 1;
 | 
				
			||||||
 | 
					    s->core = core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->state = PA_SINK_RUNNING;
 | 
				
			||||||
    s->name = pa_xstrdup(name);
 | 
					    s->name = pa_xstrdup(name);
 | 
				
			||||||
    s->description = NULL;
 | 
					    s->description = NULL;
 | 
				
			||||||
    s->typeid = typeid;
 | 
					    s->driver = pa_xstrdup(driver);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    s->ref = 1;
 | 
					 | 
				
			||||||
    s->state = PA_SINK_RUNNING;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    s->owner = NULL;
 | 
					    s->owner = NULL;
 | 
				
			||||||
    s->core = core;
 | 
					
 | 
				
			||||||
    s->sample_spec = *spec;
 | 
					    s->sample_spec = *spec;
 | 
				
			||||||
 | 
					    if (map)
 | 
				
			||||||
 | 
					        s->channel_map = *map;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        pa_channel_map_init_auto(&s->channel_map, spec->channels);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    s->inputs = pa_idxset_new(NULL, NULL);
 | 
					    s->inputs = pa_idxset_new(NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    n = pa_sprintf_malloc("%s_monitor", name);
 | 
					    n = pa_sprintf_malloc("%s_monitor", name);
 | 
				
			||||||
    s->monitor_source = pa_source_new(core, typeid, n, 0, spec);
 | 
					    s->monitor_source = pa_source_new(core, n, driver, 0, spec, map);
 | 
				
			||||||
    assert(s->monitor_source);
 | 
					    assert(s->monitor_source);
 | 
				
			||||||
    pa_xfree(n);
 | 
					    pa_xfree(n);
 | 
				
			||||||
    s->monitor_source->monitor_of = s;
 | 
					    s->monitor_source->monitor_of = s;
 | 
				
			||||||
    s->monitor_source->description = pa_sprintf_malloc("Monitor source of sink '%s'", s->name);
 | 
					    s->monitor_source->description = pa_sprintf_malloc("Monitor source of sink '%s'", s->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->volume = PA_VOLUME_NORM;
 | 
					    pa_cvolume_reset(&s->sw_volume);
 | 
				
			||||||
 | 
					    pa_cvolume_reset(&s->hw_volume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->notify = NULL;
 | 
					    s->notify = NULL;
 | 
				
			||||||
    s->get_latency = NULL;
 | 
					    s->get_latency = NULL;
 | 
				
			||||||
 | 
					    s->set_volume = NULL;
 | 
				
			||||||
 | 
					    s->get_volume = NULL;
 | 
				
			||||||
    s->userdata = NULL;
 | 
					    s->userdata = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    r = pa_idxset_put(core->sinks, s, &s->index);
 | 
					    r = pa_idxset_put(core->sinks, s, &s->index);
 | 
				
			||||||
    assert(s->index != PA_IDXSET_INVALID && r >= 0);
 | 
					    assert(s->index != PA_IDXSET_INVALID && r >= 0);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -127,6 +148,7 @@ static void sink_free(struct pa_sink *s) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_xfree(s->name);
 | 
					    pa_xfree(s->name);
 | 
				
			||||||
    pa_xfree(s->description);
 | 
					    pa_xfree(s->description);
 | 
				
			||||||
 | 
					    pa_xfree(s->driver);
 | 
				
			||||||
    pa_xfree(s);
 | 
					    pa_xfree(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -360,11 +382,38 @@ void pa_sink_set_owner(struct pa_sink *s, struct pa_module *m) {
 | 
				
			||||||
        pa_source_set_owner(s->monitor_source, m);
 | 
					        pa_source_set_owner(s->monitor_source, m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_set_volume(struct pa_sink *s, pa_volume_t volume) {
 | 
					void pa_sink_set_volume(struct pa_sink *s, pa_mixer_t m, const struct pa_cvolume *volume) {
 | 
				
			||||||
    assert(s && s->ref >= 1);
 | 
					    struct pa_cvolume *v;
 | 
				
			||||||
 | 
					    assert(s);
 | 
				
			||||||
 | 
					    assert(s->ref >= 1);
 | 
				
			||||||
 | 
					    assert(volume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->volume != volume) {
 | 
					    if ((m == PA_MIXER_HARDWARE || m == PA_MIXER_AUTO) && s->set_volume)
 | 
				
			||||||
        s->volume = volume;
 | 
					        v = &s->hw_volume;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        v = &s->sw_volume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_cvolume_equal(v, volume))
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *v = volume;
 | 
				
			||||||
    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
 | 
					    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
 | 
					    if (v == &s->hw_volume)
 | 
				
			||||||
 | 
					        s->set_volume(s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct pa_cvolume *pa_sink_get_volume(struct pa_sink *sink, pa_mixer_t m) {
 | 
				
			||||||
 | 
					    struct pa_cvolume *v;
 | 
				
			||||||
 | 
					    assert(s);
 | 
				
			||||||
 | 
					    assert(s->ref >= 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((m == PA_MIXER_HARDWARE || m == PA_MIXER_AUTO) && s->set_volume) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (s->get_volume)
 | 
				
			||||||
 | 
					            s->get_volume(s);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return &s->hw_volume;
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					        return &s->sw_volume;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										42
									
								
								polyp/sink.h
									
										
									
									
									
								
							
							
						
						
									
										42
									
								
								polyp/sink.h
									
										
									
									
									
								
							| 
						 | 
					@ -30,38 +30,51 @@ struct pa_sink;
 | 
				
			||||||
#include "sample.h"
 | 
					#include "sample.h"
 | 
				
			||||||
#include "idxset.h"
 | 
					#include "idxset.h"
 | 
				
			||||||
#include "source.h"
 | 
					#include "source.h"
 | 
				
			||||||
#include "typeid.h"
 | 
					#include "channelmap.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PA_MAX_INPUTS_PER_SINK 6
 | 
					#define PA_MAX_INPUTS_PER_SINK 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum pa_sink_state {
 | 
					typedef enum {
 | 
				
			||||||
    PA_SINK_RUNNING,
 | 
					    PA_SINK_RUNNING,
 | 
				
			||||||
    PA_SINK_DISCONNECTED
 | 
					    PA_SINK_DISCONNECTED
 | 
				
			||||||
};
 | 
					} pa_sink_state_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    PA_MIXER_AUTO,
 | 
				
			||||||
 | 
					    PA_MIXER_SOFTWARE,
 | 
				
			||||||
 | 
					    PA_MIXER_HARDWARE
 | 
				
			||||||
 | 
					} pa_mixer_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_sink {
 | 
					struct pa_sink {
 | 
				
			||||||
    int ref;
 | 
					    int ref;
 | 
				
			||||||
    enum pa_sink_state state;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint32_t index;
 | 
					    uint32_t index;
 | 
				
			||||||
    pa_typeid_t typeid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *name, *description;
 | 
					 | 
				
			||||||
    struct pa_module *owner;
 | 
					 | 
				
			||||||
    struct pa_core *core;
 | 
					    struct pa_core *core;
 | 
				
			||||||
 | 
					    pa_sink_state_t state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *name, *description, *driver;
 | 
				
			||||||
    struct pa_sample_spec sample_spec;
 | 
					    struct pa_sample_spec sample_spec;
 | 
				
			||||||
 | 
					    struct pa_channel_map channel_map;
 | 
				
			||||||
    struct pa_idxset *inputs;
 | 
					    struct pa_idxset *inputs;
 | 
				
			||||||
 | 
					    struct pa_module *owner;
 | 
				
			||||||
    struct pa_source *monitor_source;
 | 
					    struct pa_source *monitor_source;
 | 
				
			||||||
 | 
					    struct pa_cvolume hw_volume, sw_volume;
 | 
				
			||||||
    pa_volume_t volume;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void (*notify)(struct pa_sink*sink);
 | 
					    void (*notify)(struct pa_sink*sink);
 | 
				
			||||||
    pa_usec_t (*get_latency)(struct pa_sink *s);
 | 
					    pa_usec_t (*get_latency)(struct pa_sink *s);
 | 
				
			||||||
 | 
					    void (*set_volume)(struct pa_sink *s);
 | 
				
			||||||
 | 
					    void (*get_volume)(struct pa_sink *s);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    void *userdata;
 | 
					    void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_sink* pa_sink_new(struct pa_core *core, pa_typeid_t typeid, const char *name, int fail, const struct pa_sample_spec *spec);
 | 
					struct pa_sink* pa_sink_new(
 | 
				
			||||||
 | 
					    struct pa_core *core,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    int fail,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_disconnect(struct pa_sink* s);
 | 
					void pa_sink_disconnect(struct pa_sink* s);
 | 
				
			||||||
void pa_sink_unref(struct pa_sink*s);
 | 
					void pa_sink_unref(struct pa_sink*s);
 | 
				
			||||||
struct pa_sink* pa_sink_ref(struct pa_sink *s);
 | 
					struct pa_sink* pa_sink_ref(struct pa_sink *s);
 | 
				
			||||||
| 
						 | 
					@ -77,6 +90,7 @@ void pa_sink_notify(struct pa_sink*s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m);
 | 
					void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_sink_set_volume(struct pa_sink *sink, pa_volume_t volume);
 | 
					void pa_sink_set_volume(struct pa_sink *sink, pa_mixer_t m, const struct pa_cvolume *volume);
 | 
				
			||||||
 | 
					const struct pa_cvolume *pa_sink_get_volume(struct pa_sink *sink, pa_mixer_t m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,14 @@
 | 
				
			||||||
#include "subscribe.h"
 | 
					#include "subscribe.h"
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_source_output* pa_source_output_new(struct pa_source *s, pa_typeid_t typeid, const char *name, const struct pa_sample_spec *spec, int resample_method) {
 | 
					struct pa_source_output* pa_source_output_new(
 | 
				
			||||||
 | 
					    struct pa_source *s,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map,
 | 
				
			||||||
 | 
					    int resample_method) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    struct pa_source_output *o;
 | 
					    struct pa_source_output *o;
 | 
				
			||||||
    struct pa_resampler *resampler = NULL;
 | 
					    struct pa_resampler *resampler = NULL;
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
| 
						 | 
					@ -49,19 +56,24 @@ struct pa_source_output* pa_source_output_new(struct pa_source *s, pa_typeid_t t
 | 
				
			||||||
        resample_method = s->core->resample_method;
 | 
					        resample_method = s->core->resample_method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!pa_sample_spec_equal(&s->sample_spec, spec))
 | 
					    if (!pa_sample_spec_equal(&s->sample_spec, spec))
 | 
				
			||||||
        if (!(resampler = pa_resampler_new(&s->sample_spec, spec, s->core->memblock_stat, resample_method)))
 | 
					        if (!(resampler = pa_resampler_new(&s->sample_spec, &s->channel_map, spec, map, s->core->memblock_stat, resample_method)))
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    o = pa_xmalloc(sizeof(struct pa_source_output));
 | 
					    o = pa_xmalloc(sizeof(struct pa_source_output));
 | 
				
			||||||
    o->ref = 1;
 | 
					    o->ref = 1;
 | 
				
			||||||
    o->state = PA_SOURCE_OUTPUT_RUNNING;
 | 
					    o->state = PA_SOURCE_OUTPUT_RUNNING;
 | 
				
			||||||
    o->name = pa_xstrdup(name);
 | 
					    o->name = pa_xstrdup(name);
 | 
				
			||||||
    o->typeid = typeid;
 | 
					    o->driver = pa_xstrdup(driver);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    o->client = NULL;
 | 
					    o->client = NULL;
 | 
				
			||||||
    o->owner = NULL;
 | 
					    o->owner = NULL;
 | 
				
			||||||
    o->source = s;
 | 
					    o->source = s;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    o->sample_spec = *spec;
 | 
					    o->sample_spec = *spec;
 | 
				
			||||||
 | 
					    if (map)
 | 
				
			||||||
 | 
					        c->channel_map = *map;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        pa_channel_map_init_auto(&c->channel_map, spec->channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    o->push = NULL;
 | 
					    o->push = NULL;
 | 
				
			||||||
    o->kill = NULL;
 | 
					    o->kill = NULL;
 | 
				
			||||||
| 
						 | 
					@ -96,7 +108,6 @@ void pa_source_output_disconnect(struct pa_source_output*o) {
 | 
				
			||||||
    o->push = NULL;
 | 
					    o->push = NULL;
 | 
				
			||||||
    o->kill = NULL;
 | 
					    o->kill = NULL;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    o->state = PA_SOURCE_OUTPUT_DISCONNECTED;
 | 
					    o->state = PA_SOURCE_OUTPUT_DISCONNECTED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,6 +123,7 @@ static void source_output_free(struct pa_source_output* o) {
 | 
				
			||||||
        pa_resampler_free(o->resampler);
 | 
					        pa_resampler_free(o->resampler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_xfree(o->name);
 | 
					    pa_xfree(o->name);
 | 
				
			||||||
 | 
					    pa_xfree(o->driver);
 | 
				
			||||||
    pa_xfree(o);
 | 
					    pa_xfree(o);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,24 +31,24 @@
 | 
				
			||||||
#include "module.h"
 | 
					#include "module.h"
 | 
				
			||||||
#include "client.h"
 | 
					#include "client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum pa_source_output_state {
 | 
					typedef enum {
 | 
				
			||||||
    PA_SOURCE_OUTPUT_RUNNING,
 | 
					    PA_SOURCE_OUTPUT_RUNNING,
 | 
				
			||||||
    PA_SOURCE_OUTPUT_CORKED,
 | 
					    PA_SOURCE_OUTPUT_CORKED,
 | 
				
			||||||
    PA_SOURCE_OUTPUT_DISCONNECTED
 | 
					    PA_SOURCE_OUTPUT_DISCONNECTED
 | 
				
			||||||
};
 | 
					} pa_source_output_state_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_source_output {
 | 
					struct pa_source_output {
 | 
				
			||||||
    int ref;
 | 
					    int ref;
 | 
				
			||||||
    enum pa_source_output_state state;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint32_t index;
 | 
					    uint32_t index;
 | 
				
			||||||
    pa_typeid_t typeid;
 | 
					    pa_source_output_state_t state;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    char *name;
 | 
					    char *name, *driver;
 | 
				
			||||||
    struct pa_module *owner;
 | 
					    struct pa_module *owner;
 | 
				
			||||||
    struct pa_client *client;
 | 
					    struct pa_client *client;
 | 
				
			||||||
    struct pa_source *source;
 | 
					    struct pa_source *source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct pa_sample_spec sample_spec;
 | 
					    struct pa_sample_spec sample_spec;
 | 
				
			||||||
 | 
					    struct pa_channel_map channel_map;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void (*push)(struct pa_source_output *o, const struct pa_memchunk *chunk);
 | 
					    void (*push)(struct pa_source_output *o, const struct pa_memchunk *chunk);
 | 
				
			||||||
    void (*kill)(struct pa_source_output* o);
 | 
					    void (*kill)(struct pa_source_output* o);
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,14 @@ struct pa_source_output {
 | 
				
			||||||
    void *userdata;
 | 
					    void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_source_output* pa_source_output_new(struct pa_source *s, pa_typeid_t typeid, const char *name, const struct pa_sample_spec *spec, int resample_method);
 | 
					struct pa_source_output* pa_source_output_new(
 | 
				
			||||||
 | 
					    struct pa_source *s,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map;
 | 
				
			||||||
 | 
					    int resample_method);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_source_output_unref(struct pa_source_output* o);
 | 
					void pa_source_output_unref(struct pa_source_output* o);
 | 
				
			||||||
struct pa_source_output* pa_source_output_ref(struct pa_source_output *o);
 | 
					struct pa_source_output* pa_source_output_ref(struct pa_source_output *o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,11 +35,22 @@
 | 
				
			||||||
#include "subscribe.h"
 | 
					#include "subscribe.h"
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_source* pa_source_new(struct pa_core *core, pa_typeid_t typeid, const char *name, int fail, const struct pa_sample_spec *spec) {
 | 
					struct pa_source* pa_source_new(
 | 
				
			||||||
 | 
					    struct pa_core *core,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    int fail,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    struct pa_source *s;
 | 
					    struct pa_source *s;
 | 
				
			||||||
    char st[256];
 | 
					    char st[256];
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    assert(core && spec && name && *name);
 | 
					    
 | 
				
			||||||
 | 
					    assert(core);
 | 
				
			||||||
 | 
					    assert(name);
 | 
				
			||||||
 | 
					    assert(*name);
 | 
				
			||||||
 | 
					    assert(spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s = pa_xmalloc(sizeof(struct pa_source));
 | 
					    s = pa_xmalloc(sizeof(struct pa_source));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,11 +64,16 @@ struct pa_source* pa_source_new(struct pa_core *core, pa_typeid_t typeid, const
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    s->name = pa_xstrdup(name);
 | 
					    s->name = pa_xstrdup(name);
 | 
				
			||||||
    s->description = NULL;
 | 
					    s->description = NULL;
 | 
				
			||||||
    s->typeid = typeid; 
 | 
					    s->driver = pa_xstrdup(driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->owner = NULL;
 | 
					    s->owner = NULL;
 | 
				
			||||||
    s->core = core;
 | 
					    s->core = core;
 | 
				
			||||||
    s->sample_spec = *spec;
 | 
					    s->sample_spec = *spec;
 | 
				
			||||||
 | 
					    if (map)
 | 
				
			||||||
 | 
					        s->channel_map = *map;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        pa_channel_map_init_auto(&s->channel_map, spec->channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->outputs = pa_idxset_new(NULL, NULL);
 | 
					    s->outputs = pa_idxset_new(NULL, NULL);
 | 
				
			||||||
    s->monitor_of = NULL;
 | 
					    s->monitor_of = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,6 +124,7 @@ static void source_free(struct pa_source *s) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_xfree(s->name);
 | 
					    pa_xfree(s->name);
 | 
				
			||||||
    pa_xfree(s->description);
 | 
					    pa_xfree(s->description);
 | 
				
			||||||
 | 
					    pa_xfree(s->driver);
 | 
				
			||||||
    pa_xfree(s);
 | 
					    pa_xfree(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,35 +31,42 @@ struct pa_source;
 | 
				
			||||||
#include "memblock.h"
 | 
					#include "memblock.h"
 | 
				
			||||||
#include "memchunk.h"
 | 
					#include "memchunk.h"
 | 
				
			||||||
#include "sink.h"
 | 
					#include "sink.h"
 | 
				
			||||||
#include "typeid.h"
 | 
					#include "channelmap.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PA_MAX_OUTPUTS_PER_SOURCE 16
 | 
					#define PA_MAX_OUTPUTS_PER_SOURCE 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum pa_source_state {
 | 
					typedef enum {
 | 
				
			||||||
    PA_SOURCE_RUNNING,
 | 
					    PA_SOURCE_RUNNING,
 | 
				
			||||||
    PA_SOURCE_DISCONNECTED
 | 
					    PA_SOURCE_DISCONNECTED
 | 
				
			||||||
};
 | 
					} pa_source_state_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_source {
 | 
					struct pa_source {
 | 
				
			||||||
    int ref;
 | 
					    int ref;
 | 
				
			||||||
    enum pa_source_state state;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint32_t index;
 | 
					    uint32_t index;
 | 
				
			||||||
    pa_typeid_t typeid;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    char *name, *description;
 | 
					 | 
				
			||||||
    struct pa_module *owner;
 | 
					 | 
				
			||||||
    struct pa_core *core;
 | 
					    struct pa_core *core;
 | 
				
			||||||
 | 
					    pa_source_state_t state;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    char *name, *description, *driver;
 | 
				
			||||||
    struct pa_sample_spec sample_spec;
 | 
					    struct pa_sample_spec sample_spec;
 | 
				
			||||||
 | 
					    struct pa_channel_map channel_map;
 | 
				
			||||||
    struct pa_idxset *outputs;
 | 
					    struct pa_idxset *outputs;
 | 
				
			||||||
    struct pa_sink *monitor_of;
 | 
					    struct pa_sink *monitor_of;
 | 
				
			||||||
 | 
					    struct pa_module *owner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void (*notify)(struct pa_source*source);
 | 
					    void (*notify)(struct pa_source*source);
 | 
				
			||||||
    pa_usec_t (*get_latency)(struct pa_source *s);
 | 
					    pa_usec_t (*get_latency)(struct pa_source *s);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    void *userdata;
 | 
					    void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_source* pa_source_new(struct pa_core *core, pa_typeid_t typeid, const char *name, int fail, const struct pa_sample_spec *spec);
 | 
					struct pa_source* pa_source_new(
 | 
				
			||||||
 | 
					    struct pa_core *core,
 | 
				
			||||||
 | 
					    const char *name,
 | 
				
			||||||
 | 
					    const char *driver,
 | 
				
			||||||
 | 
					    int fail,
 | 
				
			||||||
 | 
					    const struct pa_sample_spec *spec,
 | 
				
			||||||
 | 
					    const struct pa_channel_map *map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_source_disconnect(struct pa_source *s);
 | 
					void pa_source_disconnect(struct pa_source *s);
 | 
				
			||||||
void pa_source_unref(struct pa_source *s);
 | 
					void pa_source_unref(struct pa_source *s);
 | 
				
			||||||
struct pa_source* pa_source_ref(struct pa_source *c);
 | 
					struct pa_source* pa_source_ref(struct pa_source *c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,8 @@ void pa_tagstruct_put_arbitrary(struct pa_tagstruct*t, const void *p, size_t len
 | 
				
			||||||
void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b);
 | 
					void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b);
 | 
				
			||||||
void pa_tagstruct_put_timeval(struct pa_tagstruct*t, const struct timeval *tv);
 | 
					void pa_tagstruct_put_timeval(struct pa_tagstruct*t, const struct timeval *tv);
 | 
				
			||||||
void pa_tagstruct_put_usec(struct pa_tagstruct*t, pa_usec_t u);
 | 
					void pa_tagstruct_put_usec(struct pa_tagstruct*t, pa_usec_t u);
 | 
				
			||||||
 | 
					void pa_tagstruct_put_channel_map(struct pa_tagstruct *t, const struct pa_channel_map *map);
 | 
				
			||||||
 | 
					void pa_tagstruct_put_cvolume(struct pa_tagstruct *t, const struct pa_cvolume *cvolume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s);
 | 
					int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s);
 | 
				
			||||||
int pa_tagstruct_getu8(struct pa_tagstruct*t, uint8_t *c);
 | 
					int pa_tagstruct_getu8(struct pa_tagstruct*t, uint8_t *c);
 | 
				
			||||||
| 
						 | 
					@ -54,6 +56,8 @@ int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t le
 | 
				
			||||||
int pa_tagstruct_get_boolean(struct pa_tagstruct *t, int *b);
 | 
					int pa_tagstruct_get_boolean(struct pa_tagstruct *t, int *b);
 | 
				
			||||||
int pa_tagstruct_get_timeval(struct pa_tagstruct*t, struct timeval *tv);
 | 
					int pa_tagstruct_get_timeval(struct pa_tagstruct*t, struct timeval *tv);
 | 
				
			||||||
int pa_tagstruct_get_usec(struct pa_tagstruct*t, pa_usec_t *u);
 | 
					int pa_tagstruct_get_usec(struct pa_tagstruct*t, pa_usec_t *u);
 | 
				
			||||||
 | 
					int pa_tagstruct_get_channel_map(struct pa_tagstruct *t, struct pa_channel_map *map);
 | 
				
			||||||
 | 
					int pa_tagstruct_get_cvolume(struct pa_tagstruct *t, struct pa_cvolume *v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_tagstruct_eof(struct pa_tagstruct*t);
 | 
					int pa_tagstruct_eof(struct pa_tagstruct*t);
 | 
				
			||||||
const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l);
 | 
					const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,13 +2,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <polyp/sample.h>
 | 
					#include <polyp/volume.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    int p;
 | 
					    pa_volume_t v;
 | 
				
			||||||
    for (p = 0; p <= 200; p++) {
 | 
					
 | 
				
			||||||
        pa_volume_t v = pa_volume_from_user((double) p/100);
 | 
					    for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) {
 | 
				
			||||||
        double dB = pa_volume_to_dB(v);
 | 
					
 | 
				
			||||||
        printf("%3i%% = %u = %0.2f dB = %u = %3i%%\n", p, v, dB, pa_volume_from_dB(dB), (int) (pa_volume_to_user(v)*100));
 | 
					        double dB = pa_sw_volume_to_dB(v);
 | 
				
			||||||
 | 
					        double f = pa_sw_volume_to_linear(v);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        printf("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i\n",
 | 
				
			||||||
 | 
					               v, (v*100)/PA_VOLUME_NORM, dB, f, pa_sw_volume_from_dB(dB), pa_sw_volume_from_linear(f));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										161
									
								
								polyp/volume.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								polyp/volume.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,161 @@
 | 
				
			||||||
 | 
					/* $Id$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***
 | 
				
			||||||
 | 
					  This file is part of polypaudio.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					  it under the terms of the GNU Lesser General Public License as published
 | 
				
			||||||
 | 
					  by the Free Software Foundation; either version 2 of the License,
 | 
				
			||||||
 | 
					  or (at your option) any later version.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio 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 Lesser General Public License
 | 
				
			||||||
 | 
					  along with polypaudio; if not, write to the Free Software
 | 
				
			||||||
 | 
					  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
				
			||||||
 | 
					  USA.
 | 
				
			||||||
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include <config.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "volume.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pa_cvolume_equal(const struct pa_cvolume *a, const struct pa_cvolume *b) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					    assert(b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (a->channels != b->channels)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (i = 0; i < a->channels; i++)
 | 
				
			||||||
 | 
					        if (a->values[i] != b->values[i])
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pa_cvolume_set(struct pa_cvolume *a, pa_volume_t v) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a->channels = PA_CHANNELS_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < a->channels; i++)
 | 
				
			||||||
 | 
					        a->values[i] = v;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pa_cvolume_reset(struct pa_cvolume *a) {
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					    pa_cvolume_set(a, PA_VOLUME_NORM);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pa_cvolume_mute(struct pa_cvolume *a) {
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					    pa_cvolume_set(a, PA_VOLUME_MUTED);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_volume_t pa_cvolume_avg(const struct pa_cvolume *a) {
 | 
				
			||||||
 | 
					    uint64_t sum = 0;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < a->channels; i++)
 | 
				
			||||||
 | 
					        sum += a->values[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sum /= a->channels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (pa_volume_t) sum;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
 | 
				
			||||||
 | 
					    uint64_t p = a;
 | 
				
			||||||
 | 
					    p *= b;
 | 
				
			||||||
 | 
					    p /= PA_VOLUME_NORM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a)* pa_sw_volume_to_linear(b));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USER_DECIBEL_RANGE 30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_volume_t pa_sw_volume_from_dB(double dB) {
 | 
				
			||||||
 | 
					    if (dB <= -USER_DECIBEL_RANGE)
 | 
				
			||||||
 | 
					        return PA_VOLUME_MUTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (pa_volume_t) ((dB/USER_DECIBEL_RANGE+1)*PA_VOLUME_NORM);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double pa_sw_volume_to_dB(pa_volume_t v) {
 | 
				
			||||||
 | 
					    if (v == PA_VOLUME_MUTED)
 | 
				
			||||||
 | 
					        return PA_DECIBEL_MININFTY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ((double) v/PA_VOLUME_NORM-1)*USER_DECIBEL_RANGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_volume_t pa_sw_volume_from_linear(double v) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (v <= 0)
 | 
				
			||||||
 | 
					        return PA_VOLUME_MUTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (v == 1)
 | 
				
			||||||
 | 
					        return PA_VOLUME_NORM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pa_sw_volume_from_dB(20*log10(v));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double pa_sw_volume_to_linear(pa_volume_t v) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (v == PA_VOLUME_MUTED)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return pow(10, pa_sw_volume_to_dB(v)/20);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *pa_cvolume_snprintf(char *s, size_t l, const struct pa_cvolume *c, unsigned channels) {
 | 
				
			||||||
 | 
					    unsigned c;
 | 
				
			||||||
 | 
					    int first = 1;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    assert(s);
 | 
				
			||||||
 | 
					    assert(l > 0);
 | 
				
			||||||
 | 
					    assert(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (channels > PA_CHANNELS_MAX || channels <= 0)
 | 
				
			||||||
 | 
					        channels = PA_CHANNELS_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *s = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (c = 0; c < channels && l > 1; c++) {
 | 
				
			||||||
 | 
					        l -= snprintf(s, l, "%s%u: %3u%%",
 | 
				
			||||||
 | 
					                      first ? "" : " ",
 | 
				
			||||||
 | 
					                      c,
 | 
				
			||||||
 | 
					                      (c->channels[c]*100)/PA_VOLUME_NORM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        s = strchr(s, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Return non-zero if the volume of all channels is equal to the specified value */
 | 
				
			||||||
 | 
					int pa_cvolume_channels_equal_to(const struct pa_cvolume *a, uint8_t channels, pa_volume_t v) {
 | 
				
			||||||
 | 
					    unsigned c;
 | 
				
			||||||
 | 
					    assert(a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (channels > PA_CHANNELS_MAX)
 | 
				
			||||||
 | 
					        channels = PA_CHANNELS_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (c = 0; c < channels; c++)
 | 
				
			||||||
 | 
					        if (a->map[c] != v)
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										98
									
								
								polyp/volume.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								polyp/volume.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					#ifndef foovolumehfoo
 | 
				
			||||||
 | 
					#define foovolumehfoo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* $Id$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***
 | 
				
			||||||
 | 
					  This file is part of polypaudio.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					  it under the terms of the GNU Lesser General Public License as published
 | 
				
			||||||
 | 
					  by the Free Software Foundation; either version 2 of the License,
 | 
				
			||||||
 | 
					  or (at your option) any later version.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio 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 Lesser General Public License
 | 
				
			||||||
 | 
					  along with polypaudio; if not, write to the Free Software
 | 
				
			||||||
 | 
					  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
				
			||||||
 | 
					  USA.
 | 
				
			||||||
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					#include <polyp/cdecl.h>
 | 
				
			||||||
 | 
					#include <polyp/sample.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \file
 | 
				
			||||||
 | 
					 * Constants and routines for volume handling */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PA_C_DECL_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Volume specification:
 | 
				
			||||||
 | 
					 *  PA_VOLUME_MUTED: silence;
 | 
				
			||||||
 | 
					 * < PA_VOLUME_NORM: decreased volume;
 | 
				
			||||||
 | 
					 *   PA_VOLUME_NORM: normal volume;
 | 
				
			||||||
 | 
					 * > PA_VOLUME_NORM: increased volume */
 | 
				
			||||||
 | 
					typedef uint32_t pa_volume_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Normal volume (100%) */
 | 
				
			||||||
 | 
					#define PA_VOLUME_NORM (0x10000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Muted volume (0%) */
 | 
				
			||||||
 | 
					#define PA_VOLUME_MUTED (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** A structure encapsulating a per-channel volume */
 | 
				
			||||||
 | 
					struct pa_cvolume {
 | 
				
			||||||
 | 
					    uint8_t channels;
 | 
				
			||||||
 | 
					    pa_volume_t values[PA_CHANNELS_MAX];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Return non-zero when *a == *b */
 | 
				
			||||||
 | 
					int pa_cvolume_equal(const struct pa_cvolume *a, const struct pa_cvolume *b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Set the volume of all channels to PA_VOLUME_NORM */
 | 
				
			||||||
 | 
					void pa_cvolume_reset(struct pa_cvolume *a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Set the volume of all channels to PA_VOLUME_MUTED */
 | 
				
			||||||
 | 
					void pa_cvolume_mute(struct pa_cvolume *a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Set the volume of all channels to the specified parameter */
 | 
				
			||||||
 | 
					void pa_cvolume_set(struct pa_cvolume *a, pa_volume_t v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Pretty print a volume structure */
 | 
				
			||||||
 | 
					char *pa_cvolume_snprintf(char *s, size_t l, const struct pa_cvolume *c, unsigned channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Return the average volume of all channels */
 | 
				
			||||||
 | 
					pa_volume_t pa_cvolume_avg(const struct pa_cvolume *a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Return non-zero if the volume of all channels is equal to the specified value */
 | 
				
			||||||
 | 
					int pa_cvolume_channels_equal_to(const struct pa_cvolume *a, uint8_t channels, pa_volume_t v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. */
 | 
				
			||||||
 | 
					pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Convert a decibel value to a volume. \since 0.4 */
 | 
				
			||||||
 | 
					pa_volume_t pa_sw_volume_from_dB(double f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Convert a volume to a decibel value.  \since 0.4 */
 | 
				
			||||||
 | 
					double pa_sw_volume_to_dB(pa_volume_t v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Convert a linear factor to a volume. \since 0.8 */
 | 
				
			||||||
 | 
					pa_volume_t pa_sw_volume_from_linear(double v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Convert a volume to a linear factor. \since 0.8 */
 | 
				
			||||||
 | 
					double pa_sw_volume_to_linear(pa_volume_t v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef INFINITY
 | 
				
			||||||
 | 
					#define PA_DECIBEL_MININFTY (-INFINITY)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					/** This value is used as minus infinity when using pa_volume_{to,from}_dB(). \since 0.4 */
 | 
				
			||||||
 | 
					#define PA_DECIBEL_MININFTY (-200)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PA_C_DECL_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue