mssndcard.c 7.38 KB
Newer Older
aymeric's avatar
aymeric committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#ifdef HAVE_CONFIG_H
#include "mediastreamer-config.h"
#endif

Simon Morlat's avatar
Simon Morlat committed
24 25
#include "mediastreamer2/mssndcard.h"

aymeric's avatar
aymeric committed
26 27 28 29 30
static MSSndCardManager *scm=NULL;

static MSSndCardManager * create_manager(){
	MSSndCardManager *obj=(MSSndCardManager *)ms_new(MSSndCardManager,1);
	obj->cards=NULL;
31
	obj->descs=NULL;
aymeric's avatar
aymeric committed
32 33 34 35 36
	return obj;
}

void ms_snd_card_manager_destroy(void){
	if (scm!=NULL){
37 38 39 40 41 42
		MSList *elem;
		for(elem=scm->descs;elem!=NULL;elem=elem->next){
			MSSndCardDesc *desc = (MSSndCardDesc*)elem->data;
			if (desc->unload!=NULL)
				desc->unload(scm);
		}
aymeric's avatar
aymeric committed
43 44
		ms_list_for_each(scm->cards,(void (*)(void*))ms_snd_card_destroy);
		ms_list_free(scm->cards);
45
		ms_list_free(scm->descs);
aymeric's avatar
aymeric committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
	}
	ms_free(scm);
	scm=NULL;
}

MSSndCardManager * ms_snd_card_manager_get(void){
	if (scm==NULL) scm=create_manager();
	return scm;
}

MSSndCard * ms_snd_card_manager_get_card(MSSndCardManager *m, const char *id){
	MSList *elem;
	for (elem=m->cards;elem!=NULL;elem=elem->next){
		MSSndCard *card=(MSSndCard*)elem->data;
		if (id==NULL) return card;
		if (strcmp(ms_snd_card_get_string_id(card),id)==0)	return card;
	}
	if (id!=NULL) ms_warning("no card with id %s",id);
	return NULL;
}

MSSndCard * ms_snd_card_manager_get_default_card(MSSndCardManager *m){
	/*return the first card that has the capture+playback capability */
	MSList *elem;
	for (elem=m->cards;elem!=NULL;elem=elem->next){
		MSSndCard *card=(MSSndCard*)elem->data;
smorlat's avatar
smorlat committed
72 73
		if ((card->capabilities & MS_SND_CARD_CAP_CAPTURE )
			&& (card->capabilities & MS_SND_CARD_CAP_PLAYBACK))
aymeric's avatar
aymeric committed
74 75 76 77 78
			return card;
	}
	return NULL;
}

79 80 81 82
MSSndCard * ms_snd_card_manager_get_default_capture_card(MSSndCardManager *m){
	MSList *elem;
	for (elem=m->cards;elem!=NULL;elem=elem->next){
		MSSndCard *card=(MSSndCard*)elem->data;
smorlat's avatar
smorlat committed
83
		if (card->capabilities & MS_SND_CARD_CAP_CAPTURE)
84 85 86 87 88 89 90 91 92
			return card;
	}
	return NULL;
}

MSSndCard * ms_snd_card_manager_get_default_playback_card(MSSndCardManager *m){
	MSList *elem;
	for (elem=m->cards;elem!=NULL;elem=elem->next){
		MSSndCard *card=(MSSndCard*)elem->data;
smorlat's avatar
smorlat committed
93
		if (card->capabilities & MS_SND_CARD_CAP_PLAYBACK)
94 95 96 97 98
			return card;
	}
	return NULL;
}

aymeric's avatar
aymeric committed
99 100 101 102 103
const MSList * ms_snd_card_manager_get_list(MSSndCardManager *m){
	return m->cards;
}

void ms_snd_card_manager_add_card(MSSndCardManager *m, MSSndCard *c){
104
	ms_message("Card '%s' added",ms_snd_card_get_string_id(c));
aymeric's avatar
aymeric committed
105 106 107
	m->cards=ms_list_append(m->cards,c);
}

108
static void card_detect(MSSndCardManager *m, MSSndCardDesc *desc){
aymeric's avatar
aymeric committed
109 110 111 112
	if (desc->detect!=NULL)
		desc->detect(m);
}

113 114 115 116 117 118 119 120 121 122 123 124 125 126
void ms_snd_card_manager_register_desc(MSSndCardManager *m, MSSndCardDesc *desc){
	m->descs=ms_list_append(m->descs,desc);
	card_detect(m,desc);
}

void ms_snd_card_manager_reload(MSSndCardManager *m){
	MSList *elem;
	ms_list_for_each(m->cards,(void (*)(void*))ms_snd_card_destroy);
	ms_list_free(m->cards);
	m->cards=NULL;
	for(elem=m->descs;elem!=NULL;elem=elem->next)
		card_detect(m,(MSSndCardDesc*)elem->data);
}

aymeric's avatar
aymeric committed
127 128 129 130 131 132 133 134
MSSndCard * ms_snd_card_dup(MSSndCard *card){
	MSSndCard *obj=NULL;
	if (card->desc->duplicate!=NULL)
		obj=card->desc->duplicate(card);
	return obj;
}

MSSndCard * ms_snd_card_new(MSSndCardDesc *desc){
135 136 137 138
	return ms_snd_card_new_with_name(desc,NULL);
}

MSSndCard * ms_snd_card_new_with_name(MSSndCardDesc *desc,const char* name) {
Simon Morlat's avatar
Simon Morlat committed
139
	MSSndCard *obj=(MSSndCard *)ms_new0(MSSndCard,1);
aymeric's avatar
aymeric committed
140
	obj->desc=desc;
141
	obj->name=name?ms_strdup(name):NULL;
aymeric's avatar
aymeric committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
	obj->data=NULL;
	obj->id=NULL;
	obj->capabilities=MS_SND_CARD_CAP_CAPTURE|MS_SND_CARD_CAP_PLAYBACK;
	if (desc->init!=NULL)
		desc->init(obj);
	return obj;
}

const char *ms_snd_card_get_driver_type(const MSSndCard *obj){
	return obj->desc->driver_type;
}

const char *ms_snd_card_get_name(const MSSndCard *obj){
	return obj->name;
}

unsigned int ms_snd_card_get_capabilities(const MSSndCard *obj){
	return obj->capabilities;
}

Simon Morlat's avatar
Simon Morlat committed
162 163 164 165
MS2_PUBLIC int ms_snd_card_get_minimal_latency(MSSndCard *obj){
	return obj->latency;
}

aymeric's avatar
aymeric committed
166 167 168 169 170 171 172 173
const char *ms_snd_card_get_string_id(MSSndCard *obj){
	if (obj->id==NULL)	obj->id=ms_strdup_printf("%s: %s",obj->desc->driver_type,obj->name);
	return obj->id;
}

void ms_snd_card_set_level(MSSndCard *obj, MSSndCardMixerElem e, int percent){
	if (obj->desc->set_level!=NULL)
		obj->desc->set_level(obj,e,percent);
174
	else ms_warning("ms_snd_card_set_level: unimplemented by %s wrapper",obj->desc->driver_type);
aymeric's avatar
aymeric committed
175 176 177 178 179 180
}

int ms_snd_card_get_level(MSSndCard *obj, MSSndCardMixerElem e){
	if (obj->desc->get_level!=NULL)
		return obj->desc->get_level(obj,e);
	else {
181
		ms_warning("ms_snd_card_get_level: unimplemented by %s wrapper",obj->desc->driver_type);
aymeric's avatar
aymeric committed
182 183 184 185 186 187 188 189 190 191
		return -1;
	}
}

void ms_snd_card_set_capture(MSSndCard *obj, MSSndCardCapture c){
	if (obj->desc->set_capture!=NULL)
		obj->desc->set_capture(obj,c);
	else ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type);
}

192
int ms_snd_card_set_control(MSSndCard *obj, MSSndCardControlElem e, int val)
193 194
{
	if (obj->desc->set_control!=NULL)
195 196 197 198 199
		return obj->desc->set_control(obj,e,val);
	else {
		ms_warning("ms_snd_card_set_control: unimplemented by %s wrapper",obj->desc->driver_type);
		return -1;
	}
200 201 202 203 204 205 206 207 208 209 210 211
}

int ms_snd_card_get_control(MSSndCard *obj, MSSndCardControlElem e)
{
	if (obj->desc->get_control!=NULL)
		return obj->desc->get_control(obj,e);
	else {
		ms_warning("ms_snd_card_get_control: unimplemented by %s wrapper",obj->desc->driver_type);
		return -1;
	}
}

aymeric's avatar
aymeric committed
212 213 214 215 216 217 218 219 220 221 222 223 224 225
struct _MSFilter * ms_snd_card_create_reader(MSSndCard *obj){
	if (obj->desc->create_reader!=NULL)
		return obj->desc->create_reader(obj);
	else ms_warning("ms_snd_card_create_reader: unimplemented by %s wrapper",obj->desc->driver_type);
	return NULL;
}

struct _MSFilter * ms_snd_card_create_writer(MSSndCard *obj){
	if (obj->desc->create_writer!=NULL)
		return obj->desc->create_writer(obj);
	else ms_warning("ms_snd_card_create_writer: unimplemented by %s wrapper",obj->desc->driver_type);
	return NULL;
}

226 227 228 229 230
void ms_snd_card_set_usage_hint(MSSndCard *obj, bool_t is_going_to_be_used){
	if (obj->desc->usage_hint!=NULL)
		return obj->desc->usage_hint(obj, is_going_to_be_used);
}

aymeric's avatar
aymeric committed
231 232 233 234 235 236 237
void ms_snd_card_destroy(MSSndCard *obj){
	if (obj->desc->uninit!=NULL) obj->desc->uninit(obj);
	if (obj->name!=NULL) ms_free(obj->name);
	if (obj->id!=NULL)	ms_free(obj->id);
	ms_free(obj);
}

jehan's avatar
jehan committed
238 239 240 241 242
int ms_snd_card_get_preferred_sample_rate(const MSSndCard *obj) {
	return obj->preferred_sample_rate;
}

int ms_snd_card_set_preferred_sample_rate(MSSndCard *obj,int rate) {
243
	obj->preferred_sample_rate=rate;
jehan's avatar
jehan committed
244 245 246
	return 0;
}

aymeric's avatar
aymeric committed
247 248 249 250 251 252
#ifdef __linux
#ifndef __ALSA_ENABLED__
MSSndCard * ms_alsa_card_new_custom(const char *pcmdev, const char *mixdev){
	ms_warning("Alsa support not available in this build of mediastreamer2");
	return NULL;
}
253 254 255 256

void ms_alsa_card_set_forced_sample_rate(int samplerate){
	ms_warning("Alsa support not available in this build of mediastreamer2");
}
aymeric's avatar
aymeric committed
257 258
#endif
#endif