mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	* modify pa_channel_map_init_auto() to take an extra argument specifying the standard to use (ALSA, AIFF, ...)
* add some more validity checks to pa_source_new(),pa_sink_new(),pa_sink_input_new(),pa_source_output_new() git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@888 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									c63cc7bb79
								
							
						
					
					
						commit
						4b6ab291a7
					
				
					 27 changed files with 237 additions and 191 deletions
				
			
		| 
						 | 
					@ -340,47 +340,3 @@ snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return elem;
 | 
					    return elem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
pa_channel_map* pa_alsa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
 | 
					 | 
				
			||||||
    assert(m);
 | 
					 | 
				
			||||||
    assert(channels > 0);
 | 
					 | 
				
			||||||
    assert(channels <= PA_CHANNELS_MAX);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pa_channel_map_init(m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    m->channels = channels;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* The standard ALSA channel order */
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    switch (channels) {
 | 
					 | 
				
			||||||
        case 1:
 | 
					 | 
				
			||||||
            m->map[0] = PA_CHANNEL_POSITION_MONO;
 | 
					 | 
				
			||||||
            return m;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        case 8:
 | 
					 | 
				
			||||||
            m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
 | 
					 | 
				
			||||||
            m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
 | 
					 | 
				
			||||||
            /* Fall through */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        case 6:
 | 
					 | 
				
			||||||
            m->map[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_POSITION_FRONT_LEFT;
 | 
					 | 
				
			||||||
            m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
 | 
					 | 
				
			||||||
            return m;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
            return NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,4 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, const pa_sample_spec *ss, uint3
 | 
				
			||||||
int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);
 | 
					int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);
 | 
				
			||||||
snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name);
 | 
					snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_channel_map* pa_alsa_channel_map_init_auto(pa_channel_map *m, unsigned channels);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -324,19 +324,8 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": failed to parse sample specification");
 | 
					        pa_log(__FILE__": failed to parse sample specification and channel map");
 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pa_alsa_channel_map_init_auto(&map, ss.channels);
 | 
					 | 
				
			||||||
    if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
 | 
					 | 
				
			||||||
        pa_log(__FILE__": invalid channel map.");
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (ss.channels != map.channels) {
 | 
					 | 
				
			||||||
        pa_log(__FILE__": channel map and sample specification don't match.");
 | 
					 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,22 +316,11 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": failed to parse sample specification");
 | 
					        pa_log(__FILE__": failed to parse sample specification");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_alsa_channel_map_init_auto(&map, ss.channels);
 | 
					 | 
				
			||||||
    if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
 | 
					 | 
				
			||||||
        pa_log(__FILE__": invalid channel map.");
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (ss.channels != map.channels) {
 | 
					 | 
				
			||||||
        pa_log(__FILE__": channel map and sample specification don't match.");
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    frame_size = pa_frame_size(&ss);
 | 
					    frame_size = pa_frame_size(&ss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Fix latency to 100ms */
 | 
					    /* Fix latency to 100ms */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -361,7 +361,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    if (ss.channels == master_sink->sample_spec.channels)
 | 
					    if (ss.channels == master_sink->sample_spec.channels)
 | 
				
			||||||
        map = master_sink->channel_map;
 | 
					        map = master_sink->channel_map;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        pa_channel_map_init_auto(&map, ss.channels);
 | 
					        pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
 | 
					    if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
 | 
				
			||||||
        pa_log(__FILE__": invalid channel map.");
 | 
					        pa_log(__FILE__": invalid channel map.");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,7 +296,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_channel_map_init_auto(&map, channels);
 | 
					    pa_channel_map_init_auto(&map, channels, PA_CHANNEL_MAP_ALSA);
 | 
				
			||||||
    if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) {
 | 
					    if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) {
 | 
				
			||||||
        pa_log(__FILE__": failed to parse channel_map= argument.");
 | 
					        pa_log(__FILE__": failed to parse channel_map= argument.");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -294,7 +294,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_channel_map_init_auto(&map, channels);
 | 
					    pa_channel_map_init_auto(&map, channels, PA_CHANNEL_MAP_ALSA);
 | 
				
			||||||
    if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) {
 | 
					    if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) {
 | 
				
			||||||
        pa_log(__FILE__": failed to parse channel_map= argument.");
 | 
					        pa_log(__FILE__": failed to parse channel_map= argument.");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,7 +104,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": invalid sample format specification or channel map.");
 | 
					        pa_log(__FILE__": invalid sample format specification or channel map.");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,7 +383,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u->sample_spec = c->default_sample_spec;
 | 
					    u->sample_spec = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->sample_spec, &map) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->sample_spec, &map, PA_CHANNEL_MAP_ALSA) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": failed to parse sample specification or channel map");
 | 
					        pa_log(__FILE__": failed to parse sample specification or channel map");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -347,7 +347,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
 | 
					    mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": failed to parse sample specification or channel map");
 | 
					        pa_log(__FILE__": failed to parse sample specification or channel map");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,7 +154,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": invalid sample format specification");
 | 
					        pa_log(__FILE__": invalid sample format specification");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,7 +132,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": invalid sample format specification or channel map");
 | 
					        pa_log(__FILE__": invalid sample format specification or channel map");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -895,7 +895,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss = c->default_sample_spec;
 | 
					    ss = c->default_sample_spec;
 | 
				
			||||||
    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
 | 
					    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
 | 
				
			||||||
        pa_log(__FILE__": invalid sample format specification");
 | 
					        pa_log(__FILE__": invalid sample format specification");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,7 +197,7 @@ int pa__init(pa_core *c, pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ss.channels != cm.channels)
 | 
					    if (ss.channels != cm.channels)
 | 
				
			||||||
        pa_channel_map_init_auto(&cm, ss.channels);
 | 
					        pa_channel_map_init_auto(&cm, ss.channels, PA_CHANNEL_MAP_AIFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    payload = pa_rtp_payload_from_sample_spec(&ss);
 | 
					    payload = pa_rtp_payload_from_sample_spec(&ss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,7 +112,7 @@ pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) {
 | 
				
			||||||
    return m;
 | 
					    return m;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
 | 
					pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) {
 | 
				
			||||||
    assert(m);
 | 
					    assert(m);
 | 
				
			||||||
    assert(channels > 0);
 | 
					    assert(channels > 0);
 | 
				
			||||||
    assert(channels <= PA_CHANNELS_MAX);
 | 
					    assert(channels <= PA_CHANNELS_MAX);
 | 
				
			||||||
| 
						 | 
					@ -121,6 +121,9 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m->channels = channels;
 | 
					    m->channels = channels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (def) {
 | 
				
			||||||
 | 
					        case PA_CHANNEL_MAP_AIFF:
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            /* This is somewhat compatible with RFC3551 */
 | 
					            /* This is somewhat compatible with RFC3551 */
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            switch (channels) {
 | 
					            switch (channels) {
 | 
				
			||||||
| 
						 | 
					@ -164,6 +167,56 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    return NULL;
 | 
					                    return NULL;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case PA_CHANNEL_MAP_ALSA:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (channels) {
 | 
				
			||||||
 | 
					                case 1:
 | 
				
			||||||
 | 
					                    m->map[0] = PA_CHANNEL_POSITION_MONO;
 | 
				
			||||||
 | 
					                    return m;
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                case 8:
 | 
				
			||||||
 | 
					                    m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
 | 
				
			||||||
 | 
					                    m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
 | 
				
			||||||
 | 
					                    /* Fall through */
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                case 6:
 | 
				
			||||||
 | 
					                    m->map[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_POSITION_FRONT_LEFT;
 | 
				
			||||||
 | 
					                    m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
 | 
				
			||||||
 | 
					                    return m;
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case PA_CHANNEL_MAP_AUX: {
 | 
				
			||||||
 | 
					            unsigned i;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (channels >= PA_CHANNELS_MAX)
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (i = 0; i < channels; i++)
 | 
				
			||||||
 | 
					                m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            return m;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,6 +120,15 @@ typedef enum pa_channel_position {
 | 
				
			||||||
    PA_CHANNEL_POSITION_MAX
 | 
					    PA_CHANNEL_POSITION_MAX
 | 
				
			||||||
} pa_channel_position_t;
 | 
					} pa_channel_position_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** A list of channel mapping definitions for pa_channel_map_init_auto() */
 | 
				
			||||||
 | 
					typedef enum pa_channel_map_def {
 | 
				
			||||||
 | 
					    PA_CHANNEL_MAP_AIFF, /**< The mapping from RFC3551, which is based on AIFF-C */
 | 
				
			||||||
 | 
					    PA_CHANNEL_MAP_ALSA, /**< The default mapping used by ALSA */
 | 
				
			||||||
 | 
					    PA_CHANNEL_MAP_AUX,  /**< Only aux channels */
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF /**< The default channel map */
 | 
				
			||||||
 | 
					} pa_channel_map_def_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** A channel map which can be used to attach labels to specific
 | 
					/** A channel map which can be used to attach labels to specific
 | 
				
			||||||
 * channels of a stream. These values are relevant for conversion and
 | 
					 * channels of a stream. These values are relevant for conversion and
 | 
				
			||||||
 * mixing of streams */
 | 
					 * mixing of streams */
 | 
				
			||||||
| 
						 | 
					@ -138,9 +147,8 @@ pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m);
 | 
				
			||||||
pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m);
 | 
					pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Initialize the specified channel map for the specified number
 | 
					/** Initialize the specified channel map for the specified number
 | 
				
			||||||
 * of channels using default labels and return a pointer to it.
 | 
					 * of channels using default labels and return a pointer to it. */
 | 
				
			||||||
 * Uses the mapping from RFC3551, which is based on AIFF-C. */
 | 
					pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def);
 | 
				
			||||||
pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Return a text label for the specified channel position */
 | 
					/** Return a text label for the specified channel position */
 | 
				
			||||||
const char* pa_channel_position_to_string(pa_channel_position_t pos);
 | 
					const char* pa_channel_position_to_string(pa_channel_position_t pos);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec *
 | 
				
			||||||
    if (map)
 | 
					    if (map)
 | 
				
			||||||
        s->channel_map = *map;
 | 
					        s->channel_map = *map;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        pa_channel_map_init_auto(&s->channel_map, ss->channels);
 | 
					        pa_channel_map_init_auto(&s->channel_map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    s->channel = 0;
 | 
					    s->channel = 0;
 | 
				
			||||||
    s->channel_valid = 0;
 | 
					    s->channel_valid = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,7 +141,7 @@ int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ss) {
 | 
					    if (ss) {
 | 
				
			||||||
        e->sample_spec = *ss;
 | 
					        e->sample_spec = *ss;
 | 
				
			||||||
        pa_channel_map_init_auto(&e->channel_map, ss->channels);
 | 
					        pa_channel_map_init_auto(&e->channel_map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
        e->volume.channels = e->sample_spec.channels;
 | 
					        e->volume.channels = e->sample_spec.channels;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,7 +280,7 @@ int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *rmap) {
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *rss, pa_channel_map *rmap) {
 | 
					int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *rss, pa_channel_map *rmap, pa_channel_map_def_t def) {
 | 
				
			||||||
    pa_sample_spec ss;
 | 
					    pa_sample_spec ss;
 | 
				
			||||||
    pa_channel_map map;
 | 
					    pa_channel_map map;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -293,7 +293,8 @@ int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *r
 | 
				
			||||||
    if (pa_modargs_get_sample_spec(ma, &ss) < 0)
 | 
					    if (pa_modargs_get_sample_spec(ma, &ss) < 0)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_channel_map_init_auto(&map, ss.channels);
 | 
					    if (!pa_channel_map_init_auto(&map, ss.channels, def))
 | 
				
			||||||
 | 
					        map.channels = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_modargs_get_channel_map(ma, &map) < 0)
 | 
					    if (pa_modargs_get_channel_map(ma, &map) < 0)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,6 @@ pa_modargs_get_channel_map(). Not always suitable, since this routine
 | 
				
			||||||
initializes the map parameter based on the channels field of the ss
 | 
					initializes the map parameter based on the channels field of the ss
 | 
				
			||||||
structure if no channel_map is found, using pa_channel_map_init_auto() */
 | 
					structure if no channel_map is found, using pa_channel_map_init_auto() */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map);
 | 
					int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map, pa_channel_map_def_t def);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,12 +101,12 @@ pa_resampler* pa_resampler_new(
 | 
				
			||||||
    if (am)
 | 
					    if (am)
 | 
				
			||||||
        r->i_cm = *am;
 | 
					        r->i_cm = *am;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels);
 | 
					        pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (bm)
 | 
					    if (bm)
 | 
				
			||||||
        r->o_cm = *bm;
 | 
					        r->o_cm = *bm;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels);
 | 
					        pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,11 +32,18 @@
 | 
				
			||||||
#include <polypcore/xmalloc.h>
 | 
					#include <polypcore/xmalloc.h>
 | 
				
			||||||
#include <polypcore/core-subscribe.h>
 | 
					#include <polypcore/core-subscribe.h>
 | 
				
			||||||
#include <polypcore/log.h>
 | 
					#include <polypcore/log.h>
 | 
				
			||||||
 | 
					#include <polypcore/utf8.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "sink-input.h"
 | 
					#include "sink-input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CONVERT_BUFFER_LENGTH 4096
 | 
					#define CONVERT_BUFFER_LENGTH 4096
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_VALIDITY_RETURN_NULL(condition) \
 | 
				
			||||||
 | 
					do {\
 | 
				
			||||||
 | 
					if (!(condition)) \
 | 
				
			||||||
 | 
					    return NULL; \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_sink_input* pa_sink_input_new(
 | 
					pa_sink_input* pa_sink_input_new(
 | 
				
			||||||
        pa_sink *s,
 | 
					        pa_sink *s,
 | 
				
			||||||
        const char *driver,
 | 
					        const char *driver,
 | 
				
			||||||
| 
						 | 
					@ -52,11 +59,25 @@ pa_sink_input* pa_sink_input_new(
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
    char st[256];
 | 
					    char st[256];
 | 
				
			||||||
    pa_channel_map tmap;
 | 
					    pa_channel_map tmap;
 | 
				
			||||||
 | 
					    pa_cvolume tvol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(s);
 | 
					    assert(s);
 | 
				
			||||||
    assert(spec);
 | 
					    assert(spec);
 | 
				
			||||||
    assert(s->state == PA_SINK_RUNNING);
 | 
					    assert(s->state == PA_SINK_RUNNING);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!map)
 | 
				
			||||||
 | 
					        map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
 | 
					    if (!volume)
 | 
				
			||||||
 | 
					        volume = pa_cvolume_reset(&tvol, spec->channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(volume && pa_cvolume_valid(volume));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(volume->channels == spec->channels);
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name));
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
    if (pa_idxset_size(s->inputs) >= PA_MAX_INPUTS_PER_SINK) {
 | 
					    if (pa_idxset_size(s->inputs) >= PA_MAX_INPUTS_PER_SINK) {
 | 
				
			||||||
        pa_log_warn(__FILE__": Failed to create sink input: too many inputs per sink.");
 | 
					        pa_log_warn(__FILE__": Failed to create sink input: too many inputs per sink.");
 | 
				
			||||||
| 
						 | 
					@ -66,19 +87,6 @@ pa_sink_input* pa_sink_input_new(
 | 
				
			||||||
    if (resample_method == PA_RESAMPLER_INVALID)
 | 
					    if (resample_method == PA_RESAMPLER_INVALID)
 | 
				
			||||||
        resample_method = s->core->resample_method;
 | 
					        resample_method = s->core->resample_method;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (map && spec->channels != map->channels)
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (volume && spec->channels != volume->channels)
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!map) {
 | 
					 | 
				
			||||||
        if (!(pa_channel_map_init_auto(&tmap, spec->channels)))
 | 
					 | 
				
			||||||
            return NULL;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        map = &tmap;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec) || !pa_channel_map_equal(map, &s->channel_map))
 | 
					    if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec) || !pa_channel_map_equal(map, &s->channel_map))
 | 
				
			||||||
        if (!(resampler = pa_resampler_new(spec, map, &s->sample_spec, &s->channel_map, 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;
 | 
				
			||||||
| 
						 | 
					@ -94,11 +102,7 @@ pa_sink_input* pa_sink_input_new(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i->sample_spec = *spec;
 | 
					    i->sample_spec = *spec;
 | 
				
			||||||
    i->channel_map = *map;
 | 
					    i->channel_map = *map;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (volume)
 | 
					 | 
				
			||||||
    i->volume = *volume;
 | 
					    i->volume = *volume;
 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        pa_cvolume_reset(&i->volume, spec->channels);
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    i->peek = NULL;
 | 
					    i->peek = NULL;
 | 
				
			||||||
    i->drop = NULL;
 | 
					    i->drop = NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <polyp/introspect.h>
 | 
					#include <polyp/introspect.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <polypcore/sink-input.h>
 | 
					#include <polypcore/sink-input.h>
 | 
				
			||||||
#include <polypcore/namereg.h>
 | 
					#include <polypcore/namereg.h>
 | 
				
			||||||
#include <polypcore/util.h>
 | 
					#include <polypcore/util.h>
 | 
				
			||||||
| 
						 | 
					@ -36,11 +37,18 @@
 | 
				
			||||||
#include <polypcore/xmalloc.h>
 | 
					#include <polypcore/xmalloc.h>
 | 
				
			||||||
#include <polypcore/core-subscribe.h>
 | 
					#include <polypcore/core-subscribe.h>
 | 
				
			||||||
#include <polypcore/log.h>
 | 
					#include <polypcore/log.h>
 | 
				
			||||||
 | 
					#include <polypcore/utf8.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "sink.h"
 | 
					#include "sink.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_MIX_CHANNELS 32
 | 
					#define MAX_MIX_CHANNELS 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_VALIDITY_RETURN_NULL(condition) \
 | 
				
			||||||
 | 
					do {\
 | 
				
			||||||
 | 
					if (!(condition)) \
 | 
				
			||||||
 | 
					    return NULL; \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_sink* pa_sink_new(
 | 
					pa_sink* pa_sink_new(
 | 
				
			||||||
        pa_core *core,
 | 
					        pa_core *core,
 | 
				
			||||||
        const char *driver,
 | 
					        const char *driver,
 | 
				
			||||||
| 
						 | 
					@ -53,12 +61,22 @@ pa_sink* pa_sink_new(
 | 
				
			||||||
    char *n = NULL;
 | 
					    char *n = NULL;
 | 
				
			||||||
    char st[256];
 | 
					    char st[256];
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
 | 
					    pa_channel_map tmap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(core);
 | 
					    assert(core);
 | 
				
			||||||
    assert(name);
 | 
					    assert(name);
 | 
				
			||||||
    assert(*name);
 | 
					 | 
				
			||||||
    assert(spec);
 | 
					    assert(spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!map)
 | 
				
			||||||
 | 
					        map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    s = pa_xnew(pa_sink, 1);
 | 
					    s = pa_xnew(pa_sink, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) {
 | 
					    if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) {
 | 
				
			||||||
| 
						 | 
					@ -75,10 +93,7 @@ pa_sink* pa_sink_new(
 | 
				
			||||||
    s->owner = NULL;
 | 
					    s->owner = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->sample_spec = *spec;
 | 
					    s->sample_spec = *spec;
 | 
				
			||||||
    if (map)
 | 
					 | 
				
			||||||
    s->channel_map = *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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ int pa_sound_file_load(const char *fname, pa_sample_spec *ss, pa_channel_map *ma
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (map)
 | 
					    if (map)
 | 
				
			||||||
        pa_channel_map_init_auto(map, ss->channels);
 | 
					        pa_channel_map_init_auto(map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if ((l = pa_frame_size(ss)*sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
 | 
					    if ((l = pa_frame_size(ss)*sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
 | 
				
			||||||
        pa_log(__FILE__": File too large");
 | 
					        pa_log(__FILE__": File too large");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,9 +31,16 @@
 | 
				
			||||||
#include <polypcore/xmalloc.h>
 | 
					#include <polypcore/xmalloc.h>
 | 
				
			||||||
#include <polypcore/core-subscribe.h>
 | 
					#include <polypcore/core-subscribe.h>
 | 
				
			||||||
#include <polypcore/log.h>
 | 
					#include <polypcore/log.h>
 | 
				
			||||||
 | 
					#include <polypcore/utf8.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "source-output.h"
 | 
					#include "source-output.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_VALIDITY_RETURN_NULL(condition) \
 | 
				
			||||||
 | 
					do {\
 | 
				
			||||||
 | 
					if (!(condition)) \
 | 
				
			||||||
 | 
					    return NULL; \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_source_output* pa_source_output_new(
 | 
					pa_source_output* pa_source_output_new(
 | 
				
			||||||
        pa_source *s,
 | 
					        pa_source *s,
 | 
				
			||||||
        const char *driver,
 | 
					        const char *driver,
 | 
				
			||||||
| 
						 | 
					@ -52,6 +59,16 @@ pa_source_output* pa_source_output_new(
 | 
				
			||||||
    assert(spec);
 | 
					    assert(spec);
 | 
				
			||||||
    assert(s->state == PA_SOURCE_RUNNING);
 | 
					    assert(s->state == PA_SOURCE_RUNNING);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!map)
 | 
				
			||||||
 | 
					        map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_idxset_size(s->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
 | 
					    if (pa_idxset_size(s->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
 | 
				
			||||||
        pa_log(__FILE__": Failed to create source output: too many outputs per source.");
 | 
					        pa_log(__FILE__": Failed to create source output: too many outputs per source.");
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
| 
						 | 
					@ -60,16 +77,11 @@ pa_source_output* pa_source_output_new(
 | 
				
			||||||
    if (resample_method == PA_RESAMPLER_INVALID)
 | 
					    if (resample_method == PA_RESAMPLER_INVALID)
 | 
				
			||||||
        resample_method = s->core->resample_method;
 | 
					        resample_method = s->core->resample_method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!map) {
 | 
					 | 
				
			||||||
        pa_channel_map_init_auto(&tmap, spec->channels);
 | 
					 | 
				
			||||||
        map = &tmap;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (!pa_sample_spec_equal(&s->sample_spec, spec) || !pa_channel_map_equal(&s->channel_map, map))
 | 
					    if (!pa_sample_spec_equal(&s->sample_spec, spec) || !pa_channel_map_equal(&s->channel_map, map))
 | 
				
			||||||
        if (!(resampler = pa_resampler_new(&s->sample_spec, &s->channel_map, spec, map, 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(pa_source_output));
 | 
					    o = pa_xnew(pa_source_output, 1);
 | 
				
			||||||
    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);
 | 
				
			||||||
| 
						 | 
					@ -137,7 +149,6 @@ static void source_output_free(pa_source_output* o) {
 | 
				
			||||||
    pa_xfree(o);
 | 
					    pa_xfree(o);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void pa_source_output_unref(pa_source_output* o) {
 | 
					void pa_source_output_unref(pa_source_output* o) {
 | 
				
			||||||
    assert(o);
 | 
					    assert(o);
 | 
				
			||||||
    assert(o->ref >= 1);
 | 
					    assert(o->ref >= 1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,16 @@
 | 
				
			||||||
#include <polypcore/core-subscribe.h>
 | 
					#include <polypcore/core-subscribe.h>
 | 
				
			||||||
#include <polypcore/log.h>
 | 
					#include <polypcore/log.h>
 | 
				
			||||||
#include <polypcore/sample-util.h>
 | 
					#include <polypcore/sample-util.h>
 | 
				
			||||||
 | 
					#include <polypcore/utf8.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "source.h"
 | 
					#include "source.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_VALIDITY_RETURN_NULL(condition) \
 | 
				
			||||||
 | 
					do {\
 | 
				
			||||||
 | 
					if (!(condition)) \
 | 
				
			||||||
 | 
					    return NULL; \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_source* pa_source_new(
 | 
					pa_source* pa_source_new(
 | 
				
			||||||
        pa_core *core,
 | 
					        pa_core *core,
 | 
				
			||||||
        const char *driver,
 | 
					        const char *driver,
 | 
				
			||||||
| 
						 | 
					@ -48,12 +55,22 @@ pa_source* pa_source_new(
 | 
				
			||||||
    pa_source *s;
 | 
					    pa_source *s;
 | 
				
			||||||
    char st[256];
 | 
					    char st[256];
 | 
				
			||||||
    int r;
 | 
					    int r;
 | 
				
			||||||
 | 
					    pa_channel_map tmap;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    assert(core);
 | 
					    assert(core);
 | 
				
			||||||
    assert(name);
 | 
					    assert(name);
 | 
				
			||||||
    assert(*name);
 | 
					 | 
				
			||||||
    assert(spec);
 | 
					    assert(spec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!map)
 | 
				
			||||||
 | 
					        map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
 | 
				
			||||||
 | 
					    CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s = pa_xnew(pa_source, 1);
 | 
					    s = pa_xnew(pa_source, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) {
 | 
					    if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) {
 | 
				
			||||||
| 
						 | 
					@ -70,10 +87,7 @@ pa_source* pa_source_new(
 | 
				
			||||||
    s->owner = NULL;
 | 
					    s->owner = NULL;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    s->sample_spec = *spec;
 | 
					    s->sample_spec = *spec;
 | 
				
			||||||
    if (map)
 | 
					 | 
				
			||||||
    s->channel_map = *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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,15 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
 | 
				
			||||||
    char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 | 
					    char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 | 
				
			||||||
    pa_channel_map map, map2;
 | 
					    pa_channel_map map, map2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_channel_map_init_auto(&map, 5);
 | 
					    pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_AIFF);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_AUX);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_ALSA);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
 | 
					    fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue