add new entry and button to trigger buddylookup

Improve buddylookup dialog

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@633 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
smorlat 2009-09-04 15:23:53 +00:00
parent c9b82c9984
commit 35519331bd
199 changed files with 152 additions and 53431 deletions

View file

@ -40,7 +40,15 @@ void linphone_gtk_buddy_lookup_window_destroyed(GtkWidget *w){
}
}
void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
static void enable_add_buddy_button(GtkWidget *w){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),TRUE);
}
static void disable_add_buddy_button(GtkWidget *w){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),FALSE);
}
GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
@ -71,6 +79,7 @@ void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (results));
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)enable_add_buddy_button,w);
#if GTK_CHECK_VERSION(2,12,0)
gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(results),LOOKUP_RESULT_ADDRESS);
#endif
@ -81,11 +90,14 @@ void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
gtk_progress_bar_set_text(pb,NULL);
gtk_dialog_add_button(GTK_DIALOG(w),GTK_STOCK_CLOSE,GTK_RESPONSE_CLOSE);
g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(-1));
gtk_widget_show(w);
return w;
}
static void enable_add_buddy_button(GtkWidget *w, gboolean val){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),val);
void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw){
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"keyword")),kw);
}
static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
@ -134,7 +146,6 @@ static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
if (results) sip_setup_context_free_results(results);
break;
}
enable_add_buddy_button(w,bls==BuddyLookupDone);
g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(bls));
return TRUE;
}
@ -176,6 +187,7 @@ static void linphone_gtk_display_lookup_results(GtkWidget *w, const MSList *resu
const MSList *elem;
store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
gtk_list_store_clear(store);
disable_add_buddy_button(gtk_widget_get_toplevel(w));
for(elem=results;elem!=NULL;elem=elem->next){
BuddyInfo *bi=(BuddyInfo*)elem->data;
gtk_list_store_append(store,&iter);
@ -204,11 +216,16 @@ void linphone_gtk_add_buddy_from_database(GtkWidget *button){
gtk_tree_model_get (model, &iter,LOOKUP_RESULT_SIP_URI , &uri,LOOKUP_RESULT_NAME, &name, -1);
addr=g_strdup_printf("%s <%s>",name,uri);
lf=linphone_friend_new_with_addr(addr);
linphone_core_add_friend(linphone_gtk_get_core(),lf);
linphone_gtk_show_friends();
g_free(addr);
g_free(uri);
g_free(name);
linphone_gtk_show_contact(lf);
}
}
/*called when double clicking on a contact */
void linphone_gtk_buddy_lookup_contact_activated(GtkWidget *treeview){
linphone_gtk_add_buddy_from_database(treeview);
gtk_widget_destroy(gtk_widget_get_toplevel(treeview));
}

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Mon Mar 9 15:48:11 2009 -->
<?xml version="1.0"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy toplevel-contextual -->
<widget class="GtkDialog" id="buddylookup">
<property name="border_width">5</property>
<property name="title" translatable="yes">Search contacts in directory</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="window_position">center-on-parent</property>
<property name="icon">linphone2.png</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<signal name="response" handler="gtk_widget_destroy"/>
<child internal-child="vbox">
@ -35,21 +35,23 @@
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property>
<child>
<widget class="GtkTreeView" id="search_results">
<property name="width_request">512</property>
<property name="height_request">140</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="row_activated" handler="linphone_gtk_buddy_lookup_contact_activated"/>
</widget>
</child>
</widget>
@ -63,7 +65,6 @@
<property name="visible">True</property>
<property name="activity_mode">True</property>
<property name="show_text">True</property>
<property name="text" translatable="yes"></property>
</widget>
<packing>
<property name="expand">False</property>
@ -79,7 +80,6 @@
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="linphone_gtk_add_buddy_from_database"/>
<child>
<widget class="GtkHBox" id="hbox1">
@ -92,6 +92,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
@ -110,6 +111,7 @@
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">0</property>
</packing>
</child>
</widget>
@ -139,7 +141,7 @@
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
@ -149,7 +151,8 @@
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>

View file

@ -226,6 +226,58 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist)
gtk_widget_get_toplevel(friendlist),"show_category")),0);
}
void linphone_gtk_show_directory_search(void){
LinphoneProxyConfig *cfg=NULL;
SipSetupContext * ssc=NULL;
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *search_box=linphone_gtk_get_widget(mw,"directory_search_box");
linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
if (cfg){
ssc=linphone_proxy_config_get_sip_setup_context(cfg);
if (ssc!=NULL && sip_setup_context_get_capabilities(ssc) & SIP_SETUP_CAP_BUDDY_LOOKUP){
GtkWidget *entry=linphone_gtk_get_widget(mw,"directory_search_entry");
gchar *tooltip;
GdkColor grey={0,40000,40000,40000};
gtk_widget_show(search_box);
tooltip=g_strdup_printf(_("Search in %s directory"),linphone_proxy_config_get_domain(cfg));
gtk_widget_modify_text(entry,GTK_STATE_NORMAL,&grey);
gtk_entry_set_text(GTK_ENTRY(entry),tooltip);
g_object_set_data(G_OBJECT(entry),"active",GINT_TO_POINTER(0));
g_free(tooltip);
return;
}
}
gtk_widget_hide(search_box);
}
gboolean linphone_gtk_directory_search_focus_out(GtkWidget *entry){
if (gtk_entry_get_text_length(GTK_ENTRY(entry))==0)
linphone_gtk_show_directory_search();
return FALSE;
}
gboolean linphone_gtk_directory_search_focus_in(GtkWidget *entry){
if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry),"active"))==0){
gtk_entry_set_text(GTK_ENTRY(entry),"");
gtk_widget_modify_text(entry,GTK_STATE_NORMAL,NULL);
g_object_set_data(G_OBJECT(entry),"active",GINT_TO_POINTER(1));
}
return FALSE;
}
void linphone_gtk_directory_search_activate(GtkWidget *entry){
LinphoneProxyConfig *cfg;
linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
GtkWidget *w=linphone_gtk_show_buddy_lookup_window(linphone_proxy_config_get_sip_setup_context(cfg));
linphone_gtk_buddy_lookup_set_keyword(w,gtk_entry_get_text(GTK_ENTRY(entry)));
}
void linphone_gtk_directory_search_button_clicked(GtkWidget *button){
linphone_gtk_directory_search_activate(
linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"directory_search_entry"));
}
void linphone_gtk_show_friends(void){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *friendlist=linphone_gtk_get_widget(mw,"contact_list");
@ -237,6 +289,8 @@ void linphone_gtk_show_friends(void){
LinphoneCore *core=linphone_gtk_get_core();
const gchar *search=NULL;
gboolean online_only=FALSE,lookup=FALSE;
linphone_gtk_show_directory_search();
if (gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))==NULL){
linphone_gtk_friend_list_init(friendlist);

View file

@ -69,10 +69,13 @@ void linphone_gtk_check_for_new_version(void);
const char *linphone_gtk_get_lang(const char *config_file);
void linphone_gtk_set_lang(const char *code);
SipSetupContext* linphone_gtk_get_default_sip_setup_context(void);
void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx);
GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx);
void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw);
void * linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, const char *purpose, float progress);
gchar *linphone_gtk_get_display_name(const char *sip_uri);
void linphone_gtk_show_directory_search(void);
/*functions controlling the in-call view*/
void linphone_gtk_show_in_call_view(void);
void linphone_gtk_show_idle_view(void);

View file

@ -366,6 +366,7 @@ static void update_video_title(){
}
static gboolean linphone_gtk_iterate(LinphoneCore *lc){
static gboolean first_time=TRUE;
unsigned long id;
static unsigned long previd=0;
static gboolean in_iterate=FALSE;
@ -374,6 +375,12 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
if (in_iterate) return TRUE;
in_iterate=TRUE;
linphone_core_iterate(lc);
if (first_time){
/*after the first call to iterate, SipSetupContexts should be ready, so take actions:*/
linphone_gtk_show_directory_search();
first_time=FALSE;
}
id=linphone_core_get_native_video_window_id(lc);
if (id!=previd || video_needs_update){
GdkWindow *w;
@ -578,8 +585,10 @@ void linphone_gtk_enable_self_view(GtkWidget *w){
void linphone_gtk_used_identity_changed(GtkWidget *w){
int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
if (sel && strlen(sel)>0) //avoid a dummy "changed" at gui startup
if (sel && strlen(sel)>0){ //avoid a dummy "changed" at gui startup
linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1));
linphone_gtk_show_directory_search();
}
}
static void linphone_gtk_show_main_window(){

View file

@ -440,6 +440,46 @@ Online users</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="directory_search_box">
<child>
<widget class="GtkEntry" id="directory_search_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="secondary_icon_stock">gtk-find</property>
<property name="secondary_icon_activatable">True</property>
<property name="secondary_icon_sensitive">True</property>
<signal name="focus_in_event" handler="linphone_gtk_directory_search_focus_in"/>
<signal name="activate" handler="linphone_gtk_directory_search_activate"/>
<signal name="icon_press" handler="linphone_gtk_directory_search_activate"/>
<signal name="focus_out_event" handler="linphone_gtk_directory_search_focus_out"/>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="directory_search_button">
<property name="label" translatable="yes">gtk-find</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_directory_search_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,16 +0,0 @@
*.lo
.deps
.libs
Makefile
Makefile.in
libmediastreamer.la
libmsspeex.la
mediastream
mstest
ring_test
test_alaw
test_gsm
test_lpc10
test_mulaw
test_rtprecv
test_speex

View file

@ -1,174 +0,0 @@
EXTRA_DIST=Makefile.ms
if BUILD_UGLIB
SUPPORTLIB=$(top_builddir)/support/libuglib.la
endif
#gdk video output
if BUILD_VIDEO
VIDEO_TESTPROGS=test_v4l test_videostream
#videoserver videoclient
endif
if BUILD_TRUESPEECH
TRUESPEECH_SOURCES = mstruespeechencoder.c mstruespeechencoder.h \
mstruespeechdecoder.c mstruespeechdecoder.h
TRUESPEECH_LIBADD = ../win32acm/libwin32acm.a
TRUESPEECH_TEST = test_truespeech
TRUESPEECH_INCLUDES = -I$(top_srcdir)/win32acm
endif
if BUILD_MEDIASTREAMER
noinst_LTLIBRARIES = libmediastreamer.la
endif
useless_files=mstcpserv.c mstcpserv.h mstcpclient.c mstcpclient.h
libmediastreamer_la_SOURCES=msfilter.c msfilter.h msutils.h waveheader.h\
mscodec.c mscodec.h \
mssoundread.c mssoundread.h \
mssoundwrite.c mssoundwrite.h \
msbuffer.c msbuffer.h \
msqueue.c msqueue.h \
msfifo.c msfifo.h \
ms.c ms.h\
mssync.c mssync.h \
msnosync.c msnosync.h \
msread.c msread.h \
mswrite.c mswrite.h \
mscopy.c mscopy.h \
msosswrite.c msosswrite.h \
msossread.c msossread.h \
msringplayer.c msringplayer.h \
msGSMencoder.c msGSMencoder.h \
msGSMdecoder.c msGSMdecoder.h \
msLPC10encoder.c msLPC10encoder.h \
msLPC10decoder.c msLPC10decoder.h \
msrtprecv.c msrtprecv.h \
msrtpsend.c msrtpsend.h \
msAlawenc.c msAlawenc.h g711common.h \
msAlawdec.c msAlawdec.h g711common.h \
msMUlawenc.c msMUlawenc.h g711common.h \
msMUlawdec.c msMUlawdec.h g711common.h \
mstimer.c mstimer.h \
msqdispatcher.c msqdispatcher.h \
msfdispatcher.c msfdispatcher.h \
sndcard.c sndcard.h \
osscard.c osscard.h\
hpuxsndcard.c \
alsacard.c alsacard.h \
jackcard.c jackcard.h \
audiostream.c mediastream.h \
$(TRUESPEECH_SOURCES)\
msspeexenc.c msspeexenc.h msspeexdec.c msspeexdec.h \
$(VIDEO_SOURCES)
if BUILD_VIDEO
libmediastreamer_la_SOURCES+=msv4l.c msv4l.h affine.c affine.h \
msavencoder.c msavencoder.h\
msavdecoder.c msavdecoder.h \
videostream.c \
msvideosource.c msvideosource.h \
mssdlout.c mssdlout.h \
rfc2429.h
endif
libmediastreamer_la_LIBADD= $(GLIB_LIBS) \
../gsmlib/libgsm.la \
../lpc10-1.5/liblpc10.la \
../oRTP/src/libortp.la \
$(JACK_LIBS)\
$(SAMPLERATE_LIBS)\
$(SUPPORTLIB) \
$(ALSA_LIBS) \
$(TRUESPEECH_LIBADD) \
$(SPEEX_LIBS) \
$(VIDEO_LIBS)
if BUILD_MEDIASTREAMER
noinst_PROGRAMS=mstest ring_test test_gsm test_lpc10 test_alaw test_mulaw \
test_speex \
test_rtprecv \
$(VIDEO_TESTPROGS) $(TRUESPEECH_TEST)
libexec_PROGRAMS=mediastream
endif
# test program to test TrueSpeech encoder and decoder objects
test_truespeech_SOURCES=test_truespeech.c
test_truespeech_LDADD=libmediastreamer.la
mstest_SOURCES=test.c
mstest_LDADD=libmediastreamer.la
#test program to test MSRingPlayer object
ring_test_SOURCES=ring_test.c
ring_test_LDADD=libmediastreamer.la
#test program to test GSM dec and enc objects
test_gsm_SOURCES=test_gsm.c
test_gsm_LDADD=libmediastreamer.la
#test program to test speex dec and enc objects
test_speex_SOURCES=test_speex.c
test_speex_LDADD=libmediastreamer.la
#test program to test LPC10-1.5 dec and enc objects
test_lpc10_SOURCES=test_lpc10.c
test_lpc10_LDADD=libmediastreamer.la
#test program to test ALAW dec and enc objects
test_alaw_SOURCES=test_alaw.c
test_alaw_LDADD=libmediastreamer.la
#test program to test MULAW dec and enc objects
test_mulaw_SOURCES=test_mulaw.c
test_mulaw_LDADD=libmediastreamer.la
#test program to test rtprecv object
test_rtprecv_SOURCES=test_rtprecv.c
test_rtprecv_LDADD=libmediastreamer.la
#test program to test full video stream
test_videostream_SOURCES=test_videostream.c
test_videostream_LDADD=libmediastreamer.la
#test program to test video4linux input plugin
test_v4l_SOURCES=test_v4l.c
test_v4l_LDADD=libmediastreamer.la
#videoserver_SOURCES=videoserver.c
#videoserver_LDADD=libmediastreamer.la
#videoclient_SOURCES=videoclient.c
#videoclient_LDADD=libmediastreamer.la
#the mediastream program that runs a processing that will be used in linphone
mediastream_SOURCES=mediastream.c
mediastream_LDADD=libmediastreamer.la
ORTP_CFLAGS=`cat $(top_builddir)/oRTP/ortp.defs`
AM_CFLAGS=$(GLIB_CFLAGS) -DG_LOG_DOMAIN=\"MediaStreamer\" $(TRUESPEECH_CFLAGS) $(IPV6_CFLAGS) $(ORTP_CFLAGS) \
$(VIDEO_CFLAGS)
INCLUDES= -I$(top_srcdir) \
-I$(top_srcdir)/mediastreamer \
-I$(top_srcdir)/oRTP/include \
-I$(top_srcdir)/gsmlib \
-I$(top_srcdir)/lpc10-1.5 \
$(SPEEX_CFLAGS) \
$(TRUESPEECH_INCLUDES)
linphone_includedir=$(includedir)/linphone
linphone_include_HEADERS=sndcard.h

View file

@ -1,34 +0,0 @@
OBJEXT=o
AR = ar
RANLIB = ranlib
DEFS= -DG_LOG_DOMAIN=\"MediaStreamer\"
INCLUDES=-I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include/ \
-I../gsmlib/ -I../lpc10-1.5 -I../oRTP
COMPILE= gcc $(DEFS) $(INCLUDES)
LIBTOOL=libtool
LDFLAGS=-L/usr/local/lib/ -lglib-1.3 -lgthread-1.3 -lpthread
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
libmediastreamer_a_OBJECTS = msfilter.$(OBJEXT) msbuffer.$(OBJEXT) \
msqueue.$(OBJEXT) msfifo.$(OBJEXT) ms.$(OBJEXT) mssync.$(OBJEXT) \
msnosync.$(OBJEXT) msread.$(OBJEXT) mswrite.$(OBJEXT) mscopy.$(OBJEXT) \
msv4lsource.$(OBJEXT) msoss.$(OBJEXT) msosswrite.$(OBJEXT) \
msossread.$(OBJEXT) msringplayer.$(OBJEXT) msGSMencoder.$(OBJEXT) \
msGSMdecoder.$(OBJEXT) msLPC10encoder.$(OBJEXT) \
msLPC10decoder.$(OBJEXT)
all: libmediastreamer.a mstest
.c.o:
$(COMPILE) -c $<
libmediastreamer.a: $(libmediastreamer_a_OBJECTS)
-rm -f libmediastreamer.a
$(AR) cru libmediastreamer.a $(libmediastreamer_a_OBJECTS)
$(RANLIB) libmediastreamer.a
mstest: test.o libmediastreamer.a
gcc -o mstest test.o libmediastreamer.a $(LDFLAGS) -Wl,-rpath /usr/local/lib

View file

@ -1,3 +0,0 @@
Mediastreamer is the library that handle all media operations: rtp streaming
from file, from soundcard, with codec transcoding, and vice-versa;-).
And also video streaming in the future.

View file

@ -1,144 +0,0 @@
/*
* affine.c -- Affine Transforms for 2d objects
* Copyright (C) 2002 Charles Yates <charles.yates@pandora.be>
* Portions Copyright (C) 2003 Dan Dennedy <dan@dennedy.org>
* ported from C++ to C
* wrote affine_scale()
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "affine.h"
static inline void Multiply( affine_transform_t *this, affine_transform_t *that )
{
double output[2][2];
register int i, j;
for ( i = 0; i < 2; i ++ )
for ( j = 0; j < 2; j ++ )
output[ i ][ j ] = this->matrix[ i ][ 0 ] * that->matrix[ j ][ 0 ] +
this->matrix[ i ][ 1 ] * that->matrix[ j ][ 1 ];
this->matrix[ 0 ][ 0 ] = output[ 0 ][ 0 ];
this->matrix[ 0 ][ 1 ] = output[ 0 ][ 1 ];
this->matrix[ 1 ][ 0 ] = output[ 1 ][ 0 ];
this->matrix[ 1 ][ 1 ] = output[ 1 ][ 1 ];
}
void affine_transform_init( affine_transform_t *this )
{
this->matrix[ 0 ][ 0 ] = 1;
this->matrix[ 0 ][ 1 ] = 0;
this->matrix[ 1 ][ 0 ] = 0;
this->matrix[ 1 ][ 1 ] = 1;
}
// Rotate by a given angle
void affine_transform_rotate( affine_transform_t *this, double angle )
{
affine_transform_t affine;
affine.matrix[ 0 ][ 0 ] = cos( angle * M_PI / 180 );
affine.matrix[ 0 ][ 1 ] = 0 - sin( angle * M_PI / 180 );
affine.matrix[ 1 ][ 0 ] = sin( angle * M_PI / 180 );
affine.matrix[ 1 ][ 1 ] = cos( angle * M_PI / 180 );
Multiply( this, &affine );
}
// Shear by a given value
void affine_transform_shear( affine_transform_t *this, double shear )
{
affine_transform_t affine;
affine.matrix[ 0 ][ 0 ] = 1;
affine.matrix[ 0 ][ 1 ] = shear;
affine.matrix[ 1 ][ 0 ] = 0;
affine.matrix[ 1 ][ 1 ] = 1;
Multiply( this, &affine );
}
void affine_transform_scale( affine_transform_t *this, double sx, double sy )
{
affine_transform_t affine;
affine.matrix[ 0 ][ 0 ] = sx;
affine.matrix[ 0 ][ 1 ] = 0;
affine.matrix[ 1 ][ 0 ] = 0;
affine.matrix[ 1 ][ 1 ] = sy;
Multiply( this, &affine );
}
// Obtain the mapped x coordinate of the input
double affine_transform_mapx( affine_transform_t *this, int x, int y )
{
return this->matrix[0][0] * x + this->matrix[0][1] * y;
}
// Obtain the mapped y coordinate of the input
double affine_transform_mapy( affine_transform_t *this, int x, int y )
{
return this->matrix[1][0] * x + this->matrix[1][1] * y;
}
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
void affine_scale( const unsigned char *src, unsigned char *dest, int src_width, int src_height, int dest_width, int dest_height, int bpp )
{
affine_transform_t affine;
double scale_x = (double) dest_width / (double) src_width;
double scale_y = (double) dest_height / (double) src_height;
register unsigned char *d = dest;
register const unsigned char *s = src;
register int i, j, k, x, y;
affine_transform_init( &affine );
if ( scale_x <= 1.0 && scale_y <= 1.0 )
{
affine_transform_scale( &affine, scale_x, scale_y );
for( j = 0; j < src_height; j++ )
for( i = 0; i < src_width; i++ )
{
x = (int) ( affine_transform_mapx( &affine, i - src_width/2, j - src_height/2 ) );
y = (int) ( affine_transform_mapy( &affine, i - src_width/2, j - src_height/2 ) );
x += dest_width/2;
x = CLAMP( x, 0, dest_width);
y += dest_height/2;
y = CLAMP( y, 0, dest_height);
s = src + (j*src_width*bpp) + i*bpp; // + (bpp-1);
d = dest + y*dest_width*bpp + x*bpp;
for ( k = 0; k < bpp; k++ )
*d++ = *s++;
}
}
else if ( scale_x > 1.0 && scale_y > 1.0 )
{
affine_transform_scale( &affine, 1.0/scale_x, 1.0/scale_y );
for( y = 0; y < dest_height; y++ )
for( x = 0; x < dest_width; x++ )
{
i = (int) ( affine_transform_mapx( &affine, x - dest_width/2, y - dest_height/2 ) );
j = (int) ( affine_transform_mapy( &affine, x - dest_width/2, y - dest_height/2 ) );
i += src_width/2;
i = CLAMP( i, 0, dest_width);
j += src_height/2;
j = CLAMP( j, 0, dest_height);
s = src + (j*src_width*bpp) + i*bpp; // + (bpp-1);
d = dest + y*dest_width*bpp + x*bpp;
for ( k = 0; k < bpp; k++ )
*d++ = *s++;
}
}
}

View file

@ -1,43 +0,0 @@
/*
* affine.h -- Affine Transforms for 2d objects
* Copyright (C) 2002 Charles Yates <charles.yates@pandora.be>
* Portions Copyright (C) 2003 Dan Dennedy <dan@dennedy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _AFFINE_H
#define _AFFINE_H
#include <math.h>
/** Affine transforms for 2d image manipulation. Current provides shearing and
rotating support.
*/
typedef struct {
double matrix[2][2];
} affine_transform_t;
void affine_transform_init( affine_transform_t *this );
void affine_transform_rotate( affine_transform_t *this, double angle );
void affine_transform_shear( affine_transform_t *this, double shear );
void affine_transform_scale( affine_transform_t *this, double sx, double sy );
double affine_transform_mapx( affine_transform_t *this, int x, int y );
double affine_transform_mapy( affine_transform_t *this, int x, int y );
void affine_scale( const unsigned char *src, unsigned char *dest, int src_width, int src_height, int dest_width, int dest_height, int bpp );
#endif

View file

@ -1,653 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "alsacard.h"
#ifdef HAVE_ALSA_ASOUNDLIB_H
static gchar *over_pcmdev=NULL;
#include "msossread.h"
#include "msosswrite.h"
#include <signal.h>
int __alsa_card_write(AlsaCard *obj,char *buf,int size);
int alsa_set_params(AlsaCard *obj, int rw, int bits, int stereo, int rate)
{
snd_pcm_hw_params_t *hwparams=NULL;
snd_pcm_sw_params_t *swparams=NULL;
snd_pcm_t *pcm_handle;
gint dir;
guint exact_uvalue;
gulong exact_ulvalue;
gint channels;
// gint fsize=0;
gint periods=8;
gint periodsize=256;
gint err;
int format;
if (rw) {
pcm_handle=obj->write_handle;
}
else pcm_handle=obj->read_handle;
/* Allocate the snd_pcm_hw_params_t structure on the stack. */
snd_pcm_hw_params_alloca(&hwparams);
/* Init hwparams with full configuration space */
if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
g_warning("alsa_set_params: Cannot configure this PCM device.\n");
return(-1);
}
if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
g_warning("alsa_set_params: Error setting access.\n");
return(-1);
}
/* Set sample format */
#ifdef WORDS_BIGENDIAN
format=SND_PCM_FORMAT_S16_BE;
#else
format=SND_PCM_FORMAT_S16_LE;
#endif
if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) < 0) {
g_warning("alsa_set_params: Error setting format.\n");
return(-1);
}
/* Set number of channels */
if (stereo) channels=2;
else channels=1;
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels) < 0) {
g_warning("alsa_set_params: Error setting channels.\n");
return(-1);
}
/* Set sample rate. If the exact rate is not supported */
/* by the hardware, use nearest possible rate. */
exact_uvalue=rate;
dir=0;
if ((err=snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_uvalue, &dir))<0){
g_warning("alsa_set_params: Error setting rate to %i:%s",rate,snd_strerror(err));
return -1;
}
if (dir != 0) {
g_warning("alsa_set_params: The rate %d Hz is not supported by your hardware.\n "
"==> Using %d Hz instead.\n", rate, exact_uvalue);
}
/* choose greater period size when rate is high */
periodsize=periodsize*(rate/8000);
/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */
/*
fsize=periodsize * periods;
exact_value=fsize;
if ((err=snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams,&exact_value)) < 0) {
g_warning("alsa_set_params: Error setting buffer size:%s",snd_strerror(err));
return(-1);
}
if (fsize!= exact_value) {
g_warning("alsa_set_params: The buffer size %d is not supported by your hardware.\n "
"==> Using %d instead.\n", fsize, exact_value);
}
*/
/* set period size */
exact_ulvalue=periodsize;
dir=0;
if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &exact_ulvalue, &dir) < 0) {
g_warning("alsa_set_params: Error setting period size.\n");
return(-1);
}
if (dir != 0) {
g_warning("alsa_set_params: The period size %d is not supported by your hardware.\n "
"==> Using %d instead.\n", periodsize, (int)exact_ulvalue);
}
periodsize=exact_ulvalue;
/* Set number of periods. Periods used to be called fragments. */
exact_uvalue=periods;
dir=0;
if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &exact_uvalue, &dir) < 0) {
g_warning("alsa_set_params: Error setting periods.\n");
return(-1);
}
if (dir != 0) {
g_warning("alsa_set_params: The number of periods %d is not supported by your hardware.\n "
"==> Using %d instead.\n", periods, exact_uvalue);
}
/* Apply HW parameter settings to */
/* PCM device and prepare device */
if ((err=snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
g_warning("alsa_set_params: Error setting HW params:%s",snd_strerror(err));
return(-1);
}
/*prepare sw params */
if (rw){
snd_pcm_sw_params_alloca(&swparams);
snd_pcm_sw_params_current(pcm_handle, swparams);
if ((err=snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,periodsize*2 ))<0){
g_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err));
return -1;
}
if ((err=snd_pcm_sw_params(pcm_handle, swparams))<0){
g_warning("alsa_set_params: Error setting SW params:%s",snd_strerror(err));
return(-1);
}
}
obj->frame_size=channels*(bits/8);
SND_CARD(obj)->bsize=periodsize*obj->frame_size;
//SND_CARD(obj)->bsize=4096;
obj->frames=periodsize;
g_message("alsa_set_params: blocksize=%i.",SND_CARD(obj)->bsize);
return SND_CARD(obj)->bsize;
}
int alsa_card_open_r(AlsaCard *obj,int bits,int stereo,int rate)
{
int bsize;
int err;
snd_pcm_t *pcm_handle;
gchar *pcmdev;
if (over_pcmdev!=NULL) pcmdev=over_pcmdev;
else pcmdev=obj->pcmdev;
if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_CAPTURE,SND_PCM_NONBLOCK) < 0) {
g_warning("alsa_card_open_r: Error opening PCM device %s\n",obj->pcmdev );
return -1;
}
g_return_val_if_fail(pcm_handle!=NULL,-1);
obj->read_handle=pcm_handle;
if ((bsize=alsa_set_params(obj,0,bits,stereo,rate))<0){
snd_pcm_close(pcm_handle);
obj->read_handle=NULL;
return -1;
}
obj->readbuf=g_malloc0(bsize);
err=snd_pcm_start(obj->read_handle);
if (err<0){
g_warning("Cannot start read pcm: %s", snd_strerror(err));
}
obj->readpos=0;
SND_CARD(obj)->bsize=bsize;
SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED;
return 0;
}
int alsa_card_open_w(AlsaCard *obj,int bits,int stereo,int rate)
{
// int err;
int bsize;
snd_pcm_t *pcm_handle;
gchar *pcmdev;
if (over_pcmdev!=NULL) pcmdev=over_pcmdev;
else pcmdev=obj->pcmdev;
if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_PLAYBACK,SND_PCM_NONBLOCK) < 0) {
g_warning("alsa_card_open_w: Error opening PCM device %s\n", obj->pcmdev);
return -1;
}
obj->write_handle=pcm_handle;
if ((bsize=alsa_set_params(obj,1,bits,stereo,rate))<0){
snd_pcm_close(pcm_handle);
obj->write_handle=NULL;
return -1;
}
obj->writebuf=g_malloc0(bsize);
obj->writepos=0;
SND_CARD(obj)->bsize=bsize;
SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED;
return 0;
}
void alsa_card_set_blocking_mode(AlsaCard *obj, gboolean yesno){
if (obj->read_handle!=NULL) snd_pcm_nonblock(obj->read_handle,!yesno);
if (obj->write_handle!=NULL) snd_pcm_nonblock(obj->write_handle,!yesno);
}
void alsa_card_close_r(AlsaCard *obj)
{
if (obj->read_handle!=NULL){
snd_pcm_close(obj->read_handle);
obj->read_handle=NULL;
g_free(obj->readbuf);
obj->readbuf=NULL;
}
}
void alsa_card_close_w(AlsaCard *obj)
{
if (obj->write_handle!=NULL){
snd_pcm_close(obj->write_handle);
obj->write_handle=NULL;
g_free(obj->writebuf);
obj->writebuf=NULL;
}
}
int alsa_card_probe(AlsaCard *obj,int bits,int stereo,int rate)
{
int ret;
ret=alsa_card_open_w(obj,bits,stereo,rate);
if (ret<0) return -1;
ret=SND_CARD(obj)->bsize;
alsa_card_close_w(obj);
return ret;
}
void alsa_card_destroy(AlsaCard *obj)
{
snd_card_uninit(SND_CARD(obj));
g_free(obj->pcmdev);
if (obj->readbuf!=0) g_free(obj->readbuf);
if (obj->writebuf!=0) g_free(obj->writebuf);
}
gboolean alsa_card_can_read(AlsaCard *obj)
{
int frames;
g_return_val_if_fail(obj->read_handle!=NULL,0);
if (obj->readpos!=0) return TRUE;
if ((frames=snd_pcm_avail_update(obj->read_handle)>=obj->frames)) return 1;
//g_message("frames=%i",frames);
return 0;
}
int __alsa_card_read(AlsaCard *obj,char *buf,int bsize)
{
int err;
sigset_t set;
sigemptyset(&set);
sigaddset(&set,SIGALRM);
sigprocmask(SIG_BLOCK,&set,NULL);
err=snd_pcm_readi(obj->read_handle,buf,bsize/obj->frame_size);
if (err<0) {
if (err!=-EPIPE){
g_warning("alsa_card_read: snd_pcm_readi() failed:%s.",snd_strerror(err));
}
snd_pcm_prepare(obj->read_handle);
err=snd_pcm_readi(obj->read_handle,buf,bsize/obj->frame_size);
if (err<0) g_warning("alsa_card_read: snd_pcm_readi() failed:%s.",snd_strerror(err));
}
sigprocmask(SIG_UNBLOCK,&set,NULL);
return err*obj->frame_size;
}
int alsa_card_read(AlsaCard *obj,char *buf,int size)
{
int err;
gint bsize=SND_CARD(obj)->bsize;
g_return_val_if_fail(obj->read_handle!=NULL,-1);
if (size<bsize){
gint canread=MIN(bsize-obj->readpos,size);
if (obj->readpos==0){
err=__alsa_card_read(obj,obj->readbuf,bsize);
}
memcpy(buf,&obj->readbuf[obj->readpos],canread);
obj->readpos+=canread;
if (obj->readpos>=bsize) obj->readpos=0;
return canread;
}else{
err=__alsa_card_read(obj,buf,size);
return err;
}
}
int __alsa_card_write(AlsaCard *obj,char *buf,int size)
{
int err;
sigset_t set;
sigemptyset(&set);
sigaddset(&set,SIGALRM);
sigprocmask(SIG_BLOCK,&set,NULL);
if ((err=snd_pcm_writei(obj->write_handle,buf,size/obj->frame_size))<0){
if (err!=-EPIPE){
g_warning("alsa_card_write: snd_pcm_writei() failed:%s.",snd_strerror(err));
}
snd_pcm_prepare(obj->write_handle);
err=snd_pcm_writei(obj->write_handle,buf,size/obj->frame_size);
if (err<0) g_warning("alsa_card_write: Error writing sound buffer (size=%i):%s",size,snd_strerror(err));
}
sigprocmask(SIG_UNBLOCK,&set,NULL);
return err;
}
int alsa_card_write(AlsaCard *obj,char *buf,int size){
int err;
gint bsize=SND_CARD(obj)->bsize;
g_return_val_if_fail(obj->write_handle!=NULL,-1);
if (size!=bsize || obj->writepos!=0)
{
gint canwrite;
gint totalwrite=0;
while(1){
canwrite=MIN(bsize-obj->writepos,size);
if (canwrite==0)
break;
memcpy(&obj->writebuf[obj->writepos],buf,canwrite);
obj->writepos+=canwrite;
if (obj->writepos>=bsize){
err=__alsa_card_write(obj,obj->writebuf,bsize);
obj->writepos=0;
}
size-=canwrite;
buf+=canwrite;
totalwrite+=canwrite;
}
return totalwrite;
}else{
return __alsa_card_write(obj,buf,bsize);
}
}
snd_mixer_t *alsa_mixer_open(AlsaCard *obj){
snd_mixer_t *mixer=NULL;
int err;
err=snd_mixer_open(&mixer,0);
if (err<0){
g_warning("Could not open alsa mixer: %s",snd_strerror(err));
return NULL;
}
if ((err = snd_mixer_attach (mixer, obj->mixdev)) < 0){
g_warning("Could not attach mixer to card: %s",snd_strerror(err));
snd_mixer_close(mixer);
return NULL;
}
if ((err = snd_mixer_selem_register (mixer, NULL, NULL)) < 0){
g_warning("snd_mixer_selem_register: %s",snd_strerror(err));
snd_mixer_close(mixer);
return NULL;
}
if ((err = snd_mixer_load (mixer)) < 0){
g_warning("snd_mixer_load: %s",snd_strerror(err));
snd_mixer_close(mixer);
return NULL;
}
obj->mixer=mixer;
return mixer;
}
void alsa_mixer_close(AlsaCard *obj){
snd_mixer_close(obj->mixer);
obj->mixer=NULL;
}
typedef enum {CAPTURE, PLAYBACK, CAPTURE_SWITCH, PLAYBACK_SWITCH} MixerAction;
static gint get_mixer_element(snd_mixer_t *mixer,const char *name, MixerAction action){
long value=0;
const char *elemname;
snd_mixer_elem_t *elem;
int err;
long sndMixerPMin;
long sndMixerPMax;
long newvol;
elem=snd_mixer_first_elem(mixer);
while (elem!=NULL){
elemname=snd_mixer_selem_get_name(elem);
//g_message("Found alsa mixer element %s.",elemname);
if (strcmp(elemname,name)==0){
switch (action){
case CAPTURE:
if (snd_mixer_selem_has_capture_volume(elem)){
snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
err=snd_mixer_selem_get_capture_volume(elem,SND_MIXER_SCHN_UNKNOWN,&newvol);
newvol-=sndMixerPMin;
value=(100*newvol)/(sndMixerPMax-sndMixerPMin);
if (err<0) g_warning("Could not get capture volume for %s:%s",name,snd_strerror(err));
//else g_message("Succesfully get capture level for %s.",elemname);
break;
}
break;
case PLAYBACK:
if (snd_mixer_selem_has_playback_volume(elem)){
snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
err=snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_FRONT_LEFT,&newvol);
newvol-=sndMixerPMin;
value=(100*newvol)/(sndMixerPMax-sndMixerPMin);
if (err<0) g_warning("Could not get playback volume for %s:%s",name,snd_strerror(err));
//else g_message("Succesfully get playback level for %s.",elemname);
break;
}
break;
case CAPTURE_SWITCH:
break;
case PLAYBACK_SWITCH:
break;
}
}
elem=snd_mixer_elem_next(elem);
}
return value;
}
static void set_mixer_element(snd_mixer_t *mixer,const char *name, gint level,MixerAction action){
const char *elemname;
snd_mixer_elem_t *elem;
long sndMixerPMin;
long sndMixerPMax;
long newvol;
elem=snd_mixer_first_elem(mixer);
while (elem!=NULL){
elemname=snd_mixer_selem_get_name(elem);
//g_message("Found alsa mixer element %s.",elemname);
if (strcmp(elemname,name)==0){
switch(action){
case CAPTURE:
if (snd_mixer_selem_has_capture_volume(elem)){
snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin;
snd_mixer_selem_set_capture_volume_all(elem,newvol);
//g_message("Succesfully set capture level for %s.",elemname);
return;
}
break;
case PLAYBACK:
if (snd_mixer_selem_has_playback_volume(elem)){
snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin;
snd_mixer_selem_set_playback_volume_all(elem,newvol);
//g_message("Succesfully set playback level for %s.",elemname);
return;
}
break;
case CAPTURE_SWITCH:
if (snd_mixer_selem_has_capture_switch(elem)){
snd_mixer_selem_set_capture_switch_all(elem,level);
//g_message("Succesfully set capture switch for %s.",elemname);
}
break;
case PLAYBACK_SWITCH:
if (snd_mixer_selem_has_playback_switch(elem)){
snd_mixer_selem_set_playback_switch_all(elem,level);
//g_message("Succesfully set capture switch for %s.",elemname);
}
break;
}
}
elem=snd_mixer_elem_next(elem);
}
return ;
}
void alsa_card_set_level(AlsaCard *obj,gint way,gint a)
{
snd_mixer_t *mixer;
mixer=alsa_mixer_open(obj);
if (mixer==NULL) return ;
switch(way){
case SND_CARD_LEVEL_GENERAL:
set_mixer_element(mixer,"Master",a,PLAYBACK);
break;
case SND_CARD_LEVEL_INPUT:
set_mixer_element(mixer,"Capture",a,CAPTURE);
break;
case SND_CARD_LEVEL_OUTPUT:
set_mixer_element(mixer,"PCM",a,PLAYBACK);
break;
default:
g_warning("oss_card_set_level: unsupported command.");
}
alsa_mixer_close(obj);
}
gint alsa_card_get_level(AlsaCard *obj,gint way)
{
snd_mixer_t *mixer;
gint value = -1;
mixer=alsa_mixer_open(obj);
if (mixer==NULL) return 0;
switch(way){
case SND_CARD_LEVEL_GENERAL:
value=get_mixer_element(mixer,"Master",PLAYBACK);
break;
case SND_CARD_LEVEL_INPUT:
value=get_mixer_element(mixer,"Capture",CAPTURE);
break;
case SND_CARD_LEVEL_OUTPUT:
value=get_mixer_element(mixer,"PCM",PLAYBACK);
break;
default:
g_warning("oss_card_set_level: unsupported command.");
}
alsa_mixer_close(obj);
return value;
}
void alsa_card_set_source(AlsaCard *obj,int source)
{
snd_mixer_t *mixer;
mixer=alsa_mixer_open(obj);
if (mixer==NULL) return;
switch (source){
case 'm':
set_mixer_element(mixer,"Mic",1,CAPTURE_SWITCH);
set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH);
break;
case 'l':
set_mixer_element(mixer,"Line",1,CAPTURE_SWITCH);
set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH);
break;
}
}
MSFilter *alsa_card_create_read_filter(AlsaCard *card)
{
MSFilter *f=ms_oss_read_new();
ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index);
return f;
}
MSFilter *alsa_card_create_write_filter(AlsaCard *card)
{
MSFilter *f=ms_oss_write_new();
ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index);
return f;
}
SndCard * alsa_card_new(gint devid)
{
AlsaCard * obj;
SndCard *base;
int err;
gchar *name=NULL;
/* carefull: this is an alsalib call despite its name! */
err=snd_card_get_name(devid,&name);
if (err<0) {
return NULL;
}
obj= g_new0(AlsaCard,1);
base= SND_CARD(obj);
snd_card_init(base);
base->card_name=g_strdup_printf("%s (Advanced Linux Sound Architecture)",name);
base->_probe=(SndCardOpenFunc)alsa_card_probe;
base->_open_r=(SndCardOpenFunc)alsa_card_open_r;
base->_open_w=(SndCardOpenFunc)alsa_card_open_w;
base->_can_read=(SndCardPollFunc)alsa_card_can_read;
base->_set_blocking_mode=(SndCardSetBlockingModeFunc)alsa_card_set_blocking_mode;
base->_read=(SndCardIOFunc)alsa_card_read;
base->_write=(SndCardIOFunc)alsa_card_write;
base->_close_r=(SndCardCloseFunc)alsa_card_close_r;
base->_close_w=(SndCardCloseFunc)alsa_card_close_w;
base->_set_rec_source=(SndCardMixerSetRecSourceFunc)alsa_card_set_source;
base->_set_level=(SndCardMixerSetLevelFunc)alsa_card_set_level;
base->_get_level=(SndCardMixerGetLevelFunc)alsa_card_get_level;
base->_destroy=(SndCardDestroyFunc)alsa_card_destroy;
base->_create_read_filter=(SndCardCreateFilterFunc)alsa_card_create_read_filter;
base->_create_write_filter=(SndCardCreateFilterFunc)alsa_card_create_write_filter;
obj->pcmdev=g_strdup_printf("plughw:%i,0",devid);
obj->mixdev=g_strdup_printf("hw:%i",devid);
obj->readbuf=NULL;
obj->writebuf=NULL;
return base;
}
gint alsa_card_manager_init(SndCardManager *m, gint index)
{
gint devindex;
gint found=0;
gchar *name=NULL;
for(devindex=0;index<MAX_SND_CARDS && devindex<MAX_SND_CARDS ;devindex++){
if (snd_card_get_name(devindex,&name)==0){
g_message("Found ALSA device: %s",name);
m->cards[index]=alsa_card_new(devindex);
m->cards[index]->index=index;
found++;
index++;
}
}
return found;
}
void alsa_card_manager_set_default_pcm_device(const gchar *pcmdev){
if (over_pcmdev!=NULL){
g_free(over_pcmdev);
}
over_pcmdev=g_strdup(pcmdev);
}
#endif

View file

@ -1,50 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <config.h>
#ifdef HAVE_ALSA_ASOUNDLIB_H
#include "sndcard.h"
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
struct _AlsaCard
{
SndCard parent;
gchar *pcmdev;
gchar *mixdev;
snd_pcm_t *read_handle;
snd_pcm_t *write_handle;
gint frame_size;
gint frames;
gchar *readbuf;
gint readpos;
gchar *writebuf;
gint writepos;
snd_mixer_t *mixer;
};
typedef struct _AlsaCard AlsaCard;
SndCard *alsa_card_new(gint dev_id);
gint alsa_card_manager_init(SndCardManager *m, gint index);
void alsa_card_manager_set_default_pcm_device(const gchar *pcmdev);
#endif

View file

@ -1,340 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mediastream.h"
#ifdef INET6
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
#define MAX_RTP_SIZE 1500
/* this code is not part of the library itself, it is part of the mediastream program */
void audio_stream_free(AudioStream *stream)
{
RtpSession *s;
RtpSession *destroyed=NULL;
if (stream->rtprecv!=NULL) {
s=ms_rtp_recv_get_session(MS_RTP_RECV(stream->rtprecv));
if (s!=NULL){
destroyed=s;
rtp_session_destroy(s);
}
ms_filter_destroy(stream->rtprecv);
}
if (stream->rtpsend!=NULL) {
s=ms_rtp_send_get_session(MS_RTP_SEND(stream->rtpsend));
if (s!=NULL){
if (s!=destroyed)
rtp_session_destroy(s);
}
ms_filter_destroy(stream->rtpsend);
}
if (stream->soundread!=NULL) ms_filter_destroy(stream->soundread);
if (stream->soundwrite!=NULL) ms_filter_destroy(stream->soundwrite);
if (stream->encoder!=NULL) ms_filter_destroy(stream->encoder);
if (stream->decoder!=NULL) ms_filter_destroy(stream->decoder);
if (stream->timer!=NULL) ms_sync_destroy(stream->timer);
g_free(stream);
}
static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'};
static void on_dtmf_received(RtpSession *s,gint dtmf,gpointer user_data)
{
AudioStream *stream=(AudioStream*)user_data;
if (dtmf>15){
g_warning("Unsupported telephone-event type.");
return;
}
g_message("Receiving dtmf %c.",dtmf_tab[dtmf]);
if (stream!=NULL){
if (strcmp(stream->soundwrite->klass->name,"OssWrite")==0)
ms_oss_write_play_dtmf(MS_OSS_WRITE(stream->soundwrite),dtmf_tab[dtmf]);
}
}
static void on_timestamp_jump(RtpSession *s,guint32* ts, gpointer user_data)
{
g_warning("The remote sip-phone has send data with a future timestamp: %u,"
"resynchronising session.",*ts);
rtp_session_reset(s);
}
static const char *ip4local="0.0.0.0";
static const char *ip6local="::";
const char *get_local_addr_for(const char *remote)
{
const char *ret;
#ifdef INET6
struct addrinfo hints, *res0;
int err;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
err = getaddrinfo(remote,"8000", &hints, &res0);
if (err!=0) {
g_warning ("get_local_addr_for: %s", gai_strerror(err));
return ip4local;
}
ret=(res0->ai_addr->sa_family==AF_INET6) ? ip6local : ip4local;
freeaddrinfo(res0);
#else
ret=ip4local;
#endif
return ret;
}
void create_duplex_rtpsession(RtpProfile *profile, int locport,char *remip,int remport,
int payload,int jitt_comp,
RtpSession **recvsend){
RtpSession *rtpr;
rtpr=rtp_session_new(RTP_SESSION_SENDRECV);
rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE);
rtp_session_set_profile(rtpr,profile);
rtp_session_set_local_addr(rtpr,get_local_addr_for(remip),locport);
if (remport>0) rtp_session_set_remote_addr(rtpr,remip,remport);
rtp_session_set_scheduling_mode(rtpr,0);
rtp_session_set_blocking_mode(rtpr,0);
rtp_session_set_payload_type(rtpr,payload);
rtp_session_set_jitter_compensation(rtpr,jitt_comp);
rtp_session_enable_adaptive_jitter_compensation(rtpr,TRUE);
/*rtp_session_signal_connect(rtpr,"timestamp_jump",(RtpCallback)on_timestamp_jump,NULL);*/
*recvsend=rtpr;
}
void create_rtp_sessions(RtpProfile *profile, int locport,char *remip,int remport,
int payload,int jitt_comp,
RtpSession **recv, RtpSession **send){
RtpSession *rtps,*rtpr;
/* creates two rtp filters to recv send streams (remote part)*/
rtps=rtp_session_new(RTP_SESSION_SENDONLY);
rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE);
rtp_session_set_profile(rtps,profile);
#ifdef INET6
rtp_session_set_local_addr(rtps,"::",locport+2);
#else
rtp_session_set_local_addr(rtps,"0.0.0.0",locport+2);
#endif
rtp_session_set_remote_addr(rtps,remip,remport);
rtp_session_set_scheduling_mode(rtps,0);
rtp_session_set_blocking_mode(rtps,0);
rtp_session_set_payload_type(rtps,payload);
rtp_session_set_jitter_compensation(rtps,jitt_comp);
rtpr=rtp_session_new(RTP_SESSION_RECVONLY);
rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE);
rtp_session_set_profile(rtpr,profile);
#ifdef INET6
rtp_session_set_local_addr(rtpr,"::",locport);
#else
rtp_session_set_local_addr(rtpr,"0.0.0.0",locport);
#endif
rtp_session_set_scheduling_mode(rtpr,0);
rtp_session_set_blocking_mode(rtpr,0);
rtp_session_set_send_payload_type(rtpr,payload);
rtp_session_set_recv_payload_type(rtpr,payload);
rtp_session_set_jitter_compensation(rtpr,jitt_comp);
rtp_session_signal_connect(rtpr,"timestamp_jump",(RtpCallback)on_timestamp_jump,(unsigned long)NULL);
*recv=rtpr;
*send=rtps;
}
AudioStream * audio_stream_start_full(RtpProfile *profile, int locport,char *remip,int remport,
int payload,int jitt_comp, gchar *infile, gchar *outfile, SndCard *playcard, SndCard *captcard)
{
AudioStream *stream=g_new0(AudioStream,1);
RtpSession *rtps,*rtpr;
PayloadType *pt;
//create_rtp_sessions(profile,locport,remip,remport,payload,jitt_comp,&rtpr,&rtps);
create_duplex_rtpsession(profile,locport,remip,remport,payload,jitt_comp,&rtpr);
rtp_session_signal_connect(rtpr,"telephone-event",(RtpCallback)on_dtmf_received,(unsigned long)stream);
rtps=rtpr;
stream->rtpsend=ms_rtp_send_new();
ms_rtp_send_set_session(MS_RTP_SEND(stream->rtpsend),rtps);
stream->rtprecv=ms_rtp_recv_new();
ms_rtp_recv_set_session(MS_RTP_RECV(stream->rtprecv),rtpr);
/* creates the local part */
if (infile==NULL) stream->soundread=snd_card_create_read_filter(captcard);
else stream->soundread=ms_read_new(infile);
if (outfile==NULL) stream->soundwrite=snd_card_create_write_filter(playcard);
else stream->soundwrite=ms_write_new(outfile);
/* creates the couple of encoder/decoder */
pt=rtp_profile_get_payload(profile,payload);
if (pt==NULL){
g_error("audiostream.c: undefined payload type.");
return NULL;
}
stream->encoder=ms_encoder_new_with_string_id(pt->mime_type);
stream->decoder=ms_decoder_new_with_string_id(pt->mime_type);
if ((stream->encoder==NULL) || (stream->decoder==NULL)){
/* big problem: we have not a registered codec for this payload...*/
audio_stream_free(stream);
g_error("mediastream.c: No decoder available for payload %i.",payload);
return NULL;
}
/* give the sound filters some properties */
ms_filter_set_property(stream->soundread,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate);
ms_filter_set_property(stream->soundwrite,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate);
/* give the encoder/decoder some parameters*/
ms_filter_set_property(stream->encoder,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate);
ms_filter_set_property(stream->encoder,MS_FILTER_PROPERTY_BITRATE,&pt->normal_bitrate);
ms_filter_set_property(stream->decoder,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate);
ms_filter_set_property(stream->decoder,MS_FILTER_PROPERTY_BITRATE,&pt->normal_bitrate);
ms_filter_set_property(stream->encoder,MS_FILTER_PROPERTY_FMTP, (void*)pt->send_fmtp);
ms_filter_set_property(stream->decoder,MS_FILTER_PROPERTY_FMTP,(void*)pt->recv_fmtp);
/* create the synchronisation source */
stream->timer=ms_timer_new();
/* and then connect all */
ms_filter_add_link(stream->soundread,stream->encoder);
ms_filter_add_link(stream->encoder,stream->rtpsend);
ms_filter_add_link(stream->rtprecv,stream->decoder);
ms_filter_add_link(stream->decoder,stream->soundwrite);
ms_sync_attach(stream->timer,stream->soundread);
ms_sync_attach(stream->timer,stream->rtprecv);
/* and start */
ms_start(stream->timer);
return stream;
}
static int defcard=0;
void audio_stream_set_default_card(int cardindex){
defcard=cardindex;
}
AudioStream * audio_stream_start_with_files(RtpProfile *prof,int locport,char *remip,
int remport,int profile,int jitt_comp,gchar *infile, gchar*outfile)
{
return audio_stream_start_full(prof,locport,remip,remport,profile,jitt_comp,infile,outfile,NULL,NULL);
}
AudioStream * audio_stream_start(RtpProfile *prof,int locport,char *remip,int remport,int profile,int jitt_comp)
{
SndCard *sndcard;
sndcard=snd_card_manager_get_card(snd_card_manager,defcard);
return audio_stream_start_full(prof,locport,remip,remport,profile,jitt_comp,NULL,NULL,sndcard,sndcard);
}
AudioStream *audio_stream_start_with_sndcards(RtpProfile *prof,int locport,char *remip,int remport,int profile,int jitt_comp,SndCard *playcard, SndCard *captcard)
{
g_return_val_if_fail(playcard!=NULL,NULL);
g_return_val_if_fail(captcard!=NULL,NULL);
return audio_stream_start_full(prof,locport,remip,remport,profile,jitt_comp,NULL,NULL,playcard,captcard);
}
void audio_stream_set_rtcp_information(AudioStream *st, const char *cname){
if (st->send_session!=NULL){
rtp_session_set_source_description(st->send_session,cname,NULL,NULL,NULL,NULL,"linphone-" LINPHONE_VERSION,
"This is free software (GPL) !");
}
}
void audio_stream_stop(AudioStream * stream)
{
ms_stop(stream->timer);
ortp_global_stats_display();
ms_sync_detach(stream->timer,stream->soundread);
ms_sync_detach(stream->timer,stream->rtprecv);
ms_filter_remove_links(stream->soundread,stream->encoder);
ms_filter_remove_links(stream->encoder,stream->rtpsend);
ms_filter_remove_links(stream->rtprecv,stream->decoder);
ms_filter_remove_links(stream->decoder,stream->soundwrite);
audio_stream_free(stream);
}
RingStream * ring_start(gchar *file,gint interval,SndCard *sndcard)
{
return ring_start_with_cb(file,interval,sndcard,NULL,NULL);
}
RingStream * ring_start_with_cb(gchar *file,gint interval,SndCard *sndcard, MSFilterNotifyFunc func,gpointer user_data)
{
RingStream *stream;
int tmp;
g_return_val_if_fail(sndcard!=NULL,NULL);
stream=g_new0(RingStream,1);
stream->source=ms_ring_player_new(file,interval);
if (stream->source==NULL) {
g_warning("Could not create ring player. Probably the ring file (%s) does not exist.",file);
return NULL;
}
if (func!=NULL) ms_filter_set_notify_func(MS_FILTER(stream->source),func,user_data);
stream->sndwrite=snd_card_create_write_filter(sndcard);
ms_filter_get_property(stream->source,MS_FILTER_PROPERTY_FREQ,&tmp);
ms_filter_set_property(stream->sndwrite,MS_FILTER_PROPERTY_FREQ,&tmp);
ms_filter_get_property(stream->source,MS_FILTER_PROPERTY_CHANNELS,&tmp);
ms_filter_set_property(stream->sndwrite,MS_FILTER_PROPERTY_CHANNELS,&tmp);
stream->timer=ms_timer_new();
ms_filter_add_link(stream->source,stream->sndwrite);
ms_sync_attach(stream->timer,stream->source);
ms_start(stream->timer);
return stream;
}
void ring_stop(RingStream *stream)
{
ms_stop(stream->timer);
ms_sync_detach(stream->timer,stream->source);
ms_sync_destroy(stream->timer);
ms_filter_remove_links(stream->source,stream->sndwrite);
ms_filter_destroy(stream->source);
ms_filter_destroy(stream->sndwrite);
g_free(stream);
}
/* returns the latency in samples if the audio device with id dev_id is openable in full duplex mode, else 0 */
gint test_audio_dev(int dev_id)
{
gint err;
SndCard *sndcard=snd_card_manager_get_card(snd_card_manager,dev_id);
if (sndcard==NULL) return -1;
err=snd_card_probe(sndcard,16,0,8000);
return err; /* return latency in number of sample */
}
gint audio_stream_send_dtmf(AudioStream *stream, gchar dtmf)
{
ms_rtp_send_dtmf(MS_RTP_SEND(stream->rtpsend), dtmf);
ms_oss_write_play_dtmf(MS_OSS_WRITE(stream->soundwrite),dtmf);
return 0;
}

View file

@ -1,171 +0,0 @@
/*
* PCM - A-Law conversion
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
* Wrapper for linphone Codec class by Simon Morlat <simon.morlat@free.fr>
*/
static inline int val_seg(int val)
{
int r = 0;
val >>= 7;
if (val & 0xf0) {
val >>= 4;
r += 4;
}
if (val & 0x0c) {
val >>= 2;
r += 2;
}
if (val & 0x02)
r += 1;
return r;
}
/*
* s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
*
* s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data.
*
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
static inline unsigned char s16_to_alaw(int pcm_val)
{
int mask;
int seg;
unsigned char aval;
if (pcm_val >= 0) {
mask = 0xD5;
} else {
mask = 0x55;
pcm_val = -pcm_val;
if (pcm_val > 0x7fff)
pcm_val = 0x7fff;
}
if (pcm_val < 256)
aval = pcm_val >> 4;
else {
/* Convert the scaled magnitude to segment number. */
seg = val_seg(pcm_val);
aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
}
return aval ^ mask;
}
/*
* alaw_to_s16() - Convert an A-law value to 16-bit linear PCM
*
*/
static inline int alaw_to_s16(unsigned char a_val)
{
int t;
int seg;
a_val ^= 0x55;
t = a_val & 0x7f;
if (t < 16)
t = (t << 4) + 8;
else {
seg = (t >> 4) & 0x07;
t = ((t & 0x0f) << 4) + 0x108;
t <<= seg -1;
}
return ((a_val & 0x80) ? t : -t);
}
/*
* s16_to_ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */
{
int mask;
int seg;
unsigned char uval;
if (pcm_val < 0) {
pcm_val = 0x84 - pcm_val;
mask = 0x7f;
} else {
pcm_val += 0x84;
mask = 0xff;
}
if (pcm_val > 0x7fff)
pcm_val = 0x7fff;
/* Convert the scaled magnitude to segment number. */
seg = val_seg(pcm_val);
/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
return uval ^ mask;
}
/*
* ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM
*
* First, a biased linear code is derived from the code word. An unbiased
* output can then be obtained by subtracting 33 from the biased code.
*
* Note that this function expects to be passed the complement of the
* original code word. This is in keeping with ISDN conventions.
*/
static inline int ulaw_to_s16(unsigned char u_val)
{
int t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & 0x0f) << 3) + 0x84;
t <<= (u_val & 0x70) >> 4;
return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
}

View file

@ -1,301 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sndcard.h"
#include "osscard.h"
#ifdef HAVE_SYS_AUDIO_H
#include <sys/audio.h>
#include "msossread.h"
#include "msosswrite.h"
#include <errno.h>
#include <fcntl.h>
int hpuxsnd_open(HpuxSndCard *obj, int bits,int stereo, int rate)
{
int fd;
int p=0,cond=0;
int i=0;
int min_size=0,blocksize=512;
/* do a quick non blocking open to be sure that we are not going to be blocked here
for the eternity */
fd=open(obj->dev_name,O_RDWR|O_NONBLOCK);
if (fd<0) return -EWOULDBLOCK;
close(fd);
/* open the device */
fd=open(obj->dev_name,O_RDWR);
g_return_val_if_fail(fd>0,-errno);
ioctl(fd,AUDIO_RESET,0);
ioctl(fd,AUDIO_SET_SAMPLE_RATE,rate);
ioctl(fd,AUDIO_SET_CHANNELS,stereo);
p=AUDIO_FORMAT_LINEAR16BIT;
ioctl(fd,AUDIO_SET_DATA_FORMAT,p);
/* ioctl(fd,AUDIO_GET_RXBUFSIZE,&min_size); does not work ? */
min_size=2048;
g_message("dsp blocksize is %i.",min_size);
obj->fd=fd;
obj->readpos=0;
obj->writepos=0;
SND_CARD(obj)->bits=bits;
SND_CARD(obj)->stereo=stereo;
SND_CARD(obj)->rate=rate;
SND_CARD(obj)->bsize=min_size;
return fd;
}
int hpux_snd_card_probe(HpuxSndCard *obj,int bits,int stereo,int rate)
{
return 2048;
}
int hpux_snd_card_open(HpuxSndCard *obj,int bits,int stereo,int rate)
{
int fd;
obj->ref++;
if (obj->fd==0){
fd=hpuxsnd_open(obj,bits,stereo,rate);
if (fd<0) {
obj->fd=0;
obj->ref--;
return -1;
}
}
SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED;
return 0;
}
void hpux_snd_card_close(HpuxSndCard *obj)
{
int i;
obj->ref--;
if (obj->ref==0) {
close(obj->fd);
obj->fd=0;
SND_CARD(obj)->flags&=~SND_CARD_FLAGS_OPENED;
}
}
void hpux_snd_card_destroy(HpuxSndCard *obj)
{
snd_card_uninit(SND_CARD(obj));
g_free(obj->dev_name);
g_free(obj->mixdev_name);
}
gboolean hpux_snd_card_can_read(HpuxSndCard *obj)
{
struct timeval tout={0,0};
int err;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(obj->fd,&fdset);
err=select(obj->fd+1,&fdset,NULL,NULL,&tout);
if (err>0) return TRUE;
else return FALSE;
}
int hpux_snd_card_read(HpuxSndCard *obj,char *buf,int size)
{
int err;
gint bsize=SND_CARD(obj)->bsize;
if (size<bsize){
gint canread=MIN(bsize-obj->readpos,size);
if (obj->readbuf==NULL) obj->readbuf=g_malloc0(bsize);
if (obj->readpos==0){
err=read(obj->fd,obj->readbuf,bsize);
if (err<0) {
g_warning("hpux_snd_card_read: read() failed:%s.",strerror(errno));
return -1;
}
}
memcpy(buf,&obj->readbuf[obj->readpos],canread);
obj->readpos+=canread;
if (obj->readpos>=bsize) obj->readpos=0;
return canread;
}else{
err=read(obj->fd,buf,size);
if (err<0) {
g_warning("hpux_snd_card_read: read-2() failed:%s.",strerror(errno));
}
return err;
}
}
int hpux_snd_card_write(HpuxSndCard *obj,char *buf,int size)
{
int err;
gint bsize=SND_CARD(obj)->bsize;
if (size<bsize){
gint canwrite=MIN(bsize-obj->writepos,size);
if (obj->writebuf==NULL) obj->writebuf=g_malloc0(bsize);
memcpy(&obj->writebuf[obj->writepos],buf,canwrite);
obj->writepos+=canwrite;
if (obj->writepos>=bsize){
err=write(obj->fd,obj->writebuf,bsize);
}
return canwrite;
}else{
return write(obj->fd,buf,bsize);
}
}
#define SND_CARD_LEVEL_TO_HPUX_LEVEL(a) (((a)*2) - 100)
#define HPUX_LEVEL_TO_SND_CARD_LEVEL(a) (((a)+200)/2)
void hpux_snd_card_set_level(HpuxSndCard *obj,gint way,gint a)
{
struct audio_gain gain;
int error,mix_fd;
g_return_if_fail(obj->mixdev_name!=NULL);
memset(&gain,0,sizeof(struct audio_gain));
switch(way){
case SND_CARD_LEVEL_GENERAL:
gain.cgain[0].monitor_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
gain.cgain[1].monitor_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
break;
case SND_CARD_LEVEL_INPUT:
gain.cgain[0].receive_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
gain.cgain[1].receive_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
break;
case SND_CARD_LEVEL_OUTPUT:
gain.cgain[0].transmit_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
gain.cgain[1].transmit_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a);
break;
default:
g_warning("hpux_snd_card_set_level: unsupported command.");
return;
}
gain.channel_mask=AUDIO_CHANNEL_RIGHT|AUDIO_CHANNEL_LEFT;
mix_fd = open(obj->mixdev_name, O_WRONLY);
g_return_if_fail(mix_fd>0);
error=ioctl(mix_fd,AUDIO_SET_GAINS,&gain);
if (error<0){
g_warning("hpux_snd_card_set_level: Could not set gains: %s",strerror(errno));
}
close(mix_fd);
}
gint hpux_snd_card_get_level(HpuxSndCard *obj,gint way)
{
struct audio_gain gain;
int p=0,mix_fd,error;
g_return_if_fail(obj->mixdev_name!=NULL);
gain.channel_mask=AUDIO_CHANNEL_RIGHT|AUDIO_CHANNEL_LEFT;
mix_fd = open(obj->mixdev_name, O_RDONLY);
g_return_if_fail(mix_fd>0);
error=ioctl(mix_fd,AUDIO_GET_GAINS,&gain);
if (error<0){
g_warning("hpux_snd_card_set_level: Could not get gains: %s",strerror(errno));
}
close(mix_fd);
switch(way){
case SND_CARD_LEVEL_GENERAL:
p=gain.cgain[0].monitor_gain;
break;
case SND_CARD_LEVEL_INPUT:
p=gain.cgain[0].receive_gain;
break;
case SND_CARD_LEVEL_OUTPUT:
p=gain.cgain[0].transmit_gain;
break;
default:
g_warning("hpux_snd_card_get_level: unsupported command.");
return -1;
}
return HPUX_LEVEL_TO_SND_CARD_LEVEL(p);
}
void hpux_snd_card_set_source(HpuxSndCard *obj,int source)
{
gint p=0;
gint mix_fd;
gint error=0;
g_return_if_fail(obj->mixdev_name!=NULL);
mix_fd=open("/dev/audio",O_WRONLY);
g_return_if_fail(mix_fd>0);
switch(source){
case 'm':
error=ioctl(mix_fd,AUDIO_SET_INPUT,AUDIO_IN_MIKE);
break;
case 'l':
error=ioctl(mix_fd,AUDIO_SET_INPUT,AUDIO_IN_LINE);
break;
default:
g_warning("hpux_snd_card_set_source: unsupported source.");
}
close(mix_fd);
}
MSFilter *hpux_snd_card_create_read_filter(HpuxSndCard *card)
{
MSFilter *f=ms_oss_read_new();
ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index);
return f;
}
MSFilter *hpux_snd_card_create_write_filter(HpuxSndCard *card)
{
MSFilter *f=ms_oss_write_new();
ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index);
return f;
}
SndCard * hpux_snd_card_new(char *devname, char *mixdev_name)
{
HpuxSndCard * obj= g_new0(HpuxSndCard,1);
SndCard *base= SND_CARD(obj);
snd_card_init(base);
obj->dev_name=g_strdup(devname);
obj->mixdev_name=g_strdup( mixdev_name);
base->card_name=g_strdup(devname);
base->_probe=(SndCardOpenFunc)hpux_snd_card_probe;
base->_open_r=(SndCardOpenFunc)hpux_snd_card_open;
base->_open_w=(SndCardOpenFunc)hpux_snd_card_open;
base->_can_read=(SndCardPollFunc)hpux_snd_card_can_read;
base->_read=(SndCardIOFunc)hpux_snd_card_read;
base->_write=(SndCardIOFunc)hpux_snd_card_write;
base->_close_r=(SndCardCloseFunc)hpux_snd_card_close;
base->_close_w=(SndCardCloseFunc)hpux_snd_card_close;
base->_set_rec_source=(SndCardMixerSetRecSourceFunc)hpux_snd_card_set_source;
base->_set_level=(SndCardMixerSetLevelFunc)hpux_snd_card_set_level;
base->_get_level=(SndCardMixerGetLevelFunc)hpux_snd_card_get_level;
base->_destroy=(SndCardDestroyFunc)hpux_snd_card_destroy;
base->_create_read_filter=(SndCardCreateFilterFunc)hpux_snd_card_create_read_filter;
base->_create_write_filter=(SndCardCreateFilterFunc)hpux_snd_card_create_write_filter;
return base;
}
#endif

View file

@ -1,574 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
JACK support
Copyright (C) 2004 Tobias Gehrig tobias@gehrig.tk
*/
#include "jackcard.h"
#ifdef __JACK_ENABLED__
#include "msossread.h"
#include "msosswrite.h"
#include <signal.h>
#define READBUFFERSIZE 524288
#define WRITEBUFFERSIZE 524288
#define BSIZE 512
/**
* jack_shutdown:
* @arg:
*
* This is the shutdown callback for this JACK application.
* It is called by JACK if the server ever shuts down or
* decides to disconnect the client.
*
*/
void
jack_shutdown (void *arg)
{
JackCard* obj = (JackCard*) arg;
obj->jack_running = FALSE;
obj->jack_active = FALSE;
obj->read.port = NULL;
if (obj->read.open)
obj->read.init = TRUE;
obj->write.port = NULL;
if (obj->write.open)
obj->write.init = TRUE;
}
int samplerate(jack_nframes_t rate, void *arg)
{
JackCard* obj = (JackCard*) arg;
int error;
obj->rate = rate;
if (obj->read.open) {
obj->read.data.src_ratio = (double)obj->read.rate / (double)obj->rate;
obj->read.data.input_frames = (long)((double)obj->read.frames/obj->read.data.src_ratio);
g_free(obj->read.data.data_in);
obj->read.data.data_in = malloc(obj->read.data.input_frames*sizeof(float));
if (obj->read.src_state)
if ((error = src_set_ratio(obj->read.src_state, obj->read.data.src_ratio)) != 0)
g_warning("Error while resetting the write samplerate: %s", src_strerror(error));
}
if (obj->write.open) {
obj->write.data.src_ratio = (double)obj->rate / (double)obj->write.rate;
obj->write.data.output_frames = (long)((double)obj->write.frames*obj->write.data.src_ratio);
g_free(obj->write.data.data_out);
obj->write.data.data_out = malloc(obj->write.data.output_frames*sizeof(float));
if (obj->write.src_state)
if ((error = src_set_ratio(obj->write.src_state, obj->write.data.src_ratio)) != 0)
g_warning("Error while resetting the write samplerate: %s", src_strerror(error));
}
return 0;
}
/*
* The process callback for this JACK application.
* It is called by JACK at the appropriate times.
* @nframes :
* @arg :
*/
int
process (jack_nframes_t nframes, void *arg)
{
JackCard* obj = (JackCard*) arg;
sample_t *out;
sample_t *in;
if (obj->clear && !obj->write.can_process) {
out = (sample_t *) jack_port_get_buffer (obj->write.port, nframes);
memset (out, 0, nframes * sizeof(sample_t));
obj->clear = FALSE;
}
if (!obj->can_process)
return 0;
if(obj->read.can_process) {
in = (sample_t *) jack_port_get_buffer (obj->read.port, nframes);
jack_ringbuffer_write (obj->read.buffer, (void *) in, sizeof(sample_t) * nframes);
}
if (obj->write.can_process) {
out = (sample_t *) jack_port_get_buffer (obj->write.port, nframes);
memset (out, 0, nframes * sizeof(sample_t));
if (obj->clear && jack_ringbuffer_read_space(obj->write.buffer) == 0) {
obj->write.can_process = FALSE;
if (!obj->read.open)
obj->can_process = FALSE;
obj->clear = FALSE;
return 0;
}
jack_ringbuffer_read (obj->write.buffer, (void *) out, sizeof(sample_t) * nframes);
}
return 0;
}
int jack_init(JackCard* obj)
{
char* client_name;
int error;
if (!obj->jack_running) {
obj->client = NULL;
client_name = g_strdup_printf("linphone-%u", g_random_int());
if ((obj->client = jack_client_new (client_name)) == NULL) {
g_warning("cannot create jack client");
g_free(client_name);
return -1;
}
g_message("Found Jack Daemon");
g_free(client_name);
/* tell the JACK server to call `process()' whenever
there is work to be done.
*/
jack_set_process_callback (obj->client, process, obj);
/* tell the JACK server to call `jack_shutdown()' if
it ever shuts down, either entirely, or if it
just decides to stop calling us.
*/
jack_on_shutdown (obj->client, jack_shutdown, obj);
jack_set_sample_rate_callback (obj->client, samplerate, obj);
obj->rate = jack_get_sample_rate (obj->client);
if (obj->rate == 0) {
g_warning ("rate is 0???");
if (jack_client_close(obj->client) != 0)
g_warning("could not close client");
return -1;
}
obj->buffer_size = jack_get_buffer_size(obj->client);
obj->jack_running = TRUE;
}
if (!obj->jack_active) {
if (jack_activate (obj->client)) {
g_warning("cannot activate jack client");
return -1;
} else obj->jack_active = TRUE;
}
if (obj->read.init) {
if (!obj->read.port && (obj->read.port = jack_port_register (obj->client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))==NULL) {
g_warning("error while trying to register input port");
return -1;
}
if (!obj->read.phys_ports && (obj->read.phys_ports = jack_get_ports (obj->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) {
g_warning("Cannot find any physical capture ports\n");
jack_port_unregister(obj->client, obj->read.port);
obj->read.port = NULL;
return -1;
}
if (!jack_port_connected(obj->read.port))
if ((error = jack_connect (obj->client, obj->read.phys_ports[0], jack_port_name (obj->read.port))) != 0) {
g_warning("cannot connect input ports: %s -> %s\n", jack_port_name (obj->read.port), obj->read.phys_ports[0]);
if (error == EEXIST) g_warning("connection already made");
else {
jack_port_unregister(obj->client, obj->read.port);
obj->read.port = NULL;
return -1;
}
}
obj->read.init = FALSE;
}
if (obj->write.init) {
if (!obj->write.port && (obj->write.port = jack_port_register (obj->client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0))==NULL) {
g_warning("error while trying to register output port");
return -1;
}
if (!obj->write.phys_ports && (obj->write.phys_ports = jack_get_ports (obj->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
g_warning("Cannot find any physical playback ports\n");
jack_port_unregister(obj->client, obj->write.port);
obj->write.port = NULL;
return -1;
}
if (!jack_port_connected(obj->write.port)) {
if ((error = jack_connect (obj->client, jack_port_name (obj->write.port), obj->write.phys_ports[0])) != 0) {
g_warning("cannot connect output ports: %s -> %s\n", jack_port_name (obj->write.port), obj->write.phys_ports[0]);
if (error == EEXIST) g_warning("connection already made");
else {
jack_port_unregister(obj->client, obj->write.port);
obj->write.port = NULL;
return -1;
}
}
if ((error = jack_connect (obj->client, jack_port_name (obj->write.port), obj->write.phys_ports[1])) != 0) {
g_warning("cannot connect output ports: %s -> %s\n", jack_port_name (obj->write.port), obj->write.phys_ports[1]);
if (error == EEXIST) g_warning("connection already made");
else {
jack_port_unregister(obj->client, obj->write.port);
obj->write.port = NULL;
return -1;
}
}
}
obj->write.init = FALSE;
}
return 0;
}
int jack_card_open_r(JackCard *obj,int bits,int stereo,int rate)
{
int channels = stereo + 1, bsize, error;
obj->read.init = TRUE;
if (jack_init(obj) != 0) return -1;
obj->read.rate = rate;
obj->sample_size = bits / 8;
obj->frame_size = channels * obj->sample_size;
bsize = BSIZE;
obj->read.frames = bsize / 2;
SND_CARD(obj)->bsize = bsize;
SND_CARD(obj)->flags |= SND_CARD_FLAGS_OPENED;
obj->read.channels = channels;
if ((obj->read.src_state = src_new (SRC_SINC_FASTEST, channels, &error)) == NULL)
g_warning("Error while initializing the samplerate converter: %s", src_strerror(error));
obj->read.data.src_ratio = (double)rate / (double)obj->rate;
obj->read.data.input_frames = (long)((double)obj->read.frames/obj->read.data.src_ratio);
obj->read.data.data_in = malloc(obj->read.data.input_frames*sizeof(float));
obj->read.data.data_out = malloc(obj->read.frames*sizeof(float));
obj->read.data.end_of_input = 0;
if (!obj->read.buffer)
obj->read.buffer = jack_ringbuffer_create(READBUFFERSIZE);
obj->read.can_process = TRUE;
obj->can_process = TRUE;
obj->read.open = TRUE;
obj->read.init = FALSE;
return 0;
}
int jack_card_open_w(JackCard *obj,int bits,int stereo,int rate)
{
int channels = stereo + 1, bsize, err;
obj->write.init = TRUE;
if (jack_init(obj) != 0) return -1;
obj->write.rate = rate;
obj->sample_size = bits / 8;
obj->frame_size = channels * obj->sample_size;
bsize = BSIZE;
obj->write.frames = bsize / 2;
SND_CARD(obj)->bsize = bsize;
SND_CARD(obj)->flags |= SND_CARD_FLAGS_OPENED;
obj->write.channels = channels;
if ((obj->write.src_state = src_new (SRC_SINC_FASTEST, channels, &err)) == NULL)
g_warning("Error while initializing the samplerate converter: %s", src_strerror(err));
obj->write.data.src_ratio = (double)obj->rate / (double)rate;
obj->write.data.data_in = malloc(obj->write.frames*sizeof(float));
obj->write.data.end_of_input = 0;
obj->write.data.output_frames = (long)((double)obj->write.frames*obj->write.data.src_ratio);
obj->write.data.data_out = malloc(obj->write.data.output_frames*sizeof(float));
if (!obj->write.buffer)
obj->write.buffer = jack_ringbuffer_create(WRITEBUFFERSIZE);
obj->write.can_process = TRUE;
obj->can_process = TRUE;
obj->write.open = TRUE;
obj->write.init = FALSE;
return 0;
}
void jack_card_set_blocking_mode(JackCard *obj, gboolean yesno)
{
}
void jack_card_close_r(JackCard *obj)
{
obj->read.open = FALSE;
obj->read.init = FALSE;
obj->read.can_process = FALSE;
if (!obj->write.open)
obj->can_process = FALSE;
if (obj->read.src_state)
obj->read.src_state = src_delete (obj->read.src_state);
g_free(obj->read.data.data_in);
g_free(obj->read.data.data_out);
}
void jack_card_close_w(JackCard *obj)
{
obj->write.open = FALSE;
obj->write.init = FALSE;
obj->clear = TRUE;
if (!obj->jack_running) {
obj->write.can_process = FALSE;
obj->can_process = FALSE;
}
if (obj->write.src_state)
obj->write.src_state = src_delete (obj->write.src_state);
g_free(obj->write.data.data_in);
g_free(obj->write.data.data_out);
}
int jack_card_probe(JackCard *obj,int bits,int stereo,int rate)
{
if (obj->jack_running) return BSIZE;
else if (jack_init(obj) == 0) return BSIZE;
else return -1;
}
void jack_card_destroy(JackCard *obj)
{
if (obj->jack_running) jack_client_close (obj->client);
snd_card_uninit(SND_CARD(obj));
if (obj->read.buffer) {
jack_ringbuffer_free(obj->read.buffer);
obj->read.buffer = NULL;
}
if (obj->write.buffer) {
jack_ringbuffer_free(obj->write.buffer);
obj->write.buffer = NULL;
}
if (obj->read.phys_ports) {
g_free(obj->read.phys_ports);
obj->read.phys_ports = NULL;
}
if (obj->write.phys_ports) {
g_free(obj->write.phys_ports);
obj->write.phys_ports = NULL;
}
}
gboolean jack_card_can_read(JackCard *obj)
{
g_return_val_if_fail(obj->read.buffer!=NULL,0);
if (jack_ringbuffer_read_space(obj->read.buffer)>=(long)((double)obj->read.frames/obj->read.data.src_ratio)*sizeof(sample_t)) return TRUE;
else return FALSE;
}
int jack_card_read(JackCard *obj,char *buf,int size)
{
size_t bytes, can_read, i;
int error;
float norm, value;
g_return_val_if_fail((obj->read.buffer!=NULL)&&(obj->read.src_state!=NULL),-1);
if (jack_init(obj) != 0) return -1;
size /= 2;
can_read = MIN(size, obj->read.frames);
// can_read = MIN(((long)((double)can_read / obj->read.data.src_ratio))*sizeof(sample_t), jack_ringbuffer_read_space(obj->read.buffer));
can_read = ((long)((double)can_read / obj->read.data.src_ratio))*sizeof(sample_t);
obj->read.can_process = FALSE;
bytes = jack_ringbuffer_read (obj->read.buffer, (void *)obj->read.data.data_in, can_read);
obj->read.can_process = TRUE;
obj->read.data.input_frames = bytes / sizeof(sample_t);
can_read = MIN(size, obj->read.frames);
obj->read.data.output_frames = can_read;
if ((error = src_process(obj->read.src_state, &(obj->read.data))) != 0)
g_warning("error while samplerate conversion. error: %s", src_strerror(error));
norm = obj->read.level*obj->level*(float)0x8000;
for (i=0; i < obj->read.data.output_frames_gen; i++) {
value = obj->read.data.data_out[i]*norm;
if (value >= 32767.0)
((short*)buf)[i] = 32767;
else if (value <= -32768.0)
((short*)buf)[i] = -32768;
else
((short*)buf)[i] = (short)value;
}
bytes = obj->read.data.output_frames_gen * 2;
return bytes;
}
int jack_card_write(JackCard *obj,char *buf,int size)
{
size_t bytes, can_write, i;
int error;
float norm;
g_return_val_if_fail((obj->write.buffer!=NULL)&&(obj->write.src_state!=NULL),-1);
if (jack_init(obj) != 0) return -1;
size /= 2;
can_write = MIN(size, obj->write.frames);
norm = obj->write.level*obj->level/(float)0x8000;
for (i=0; i<can_write; i++) {
obj->write.data.data_in[i] = (float)((short*)buf)[i]*norm;
}
obj->write.data.input_frames = can_write;
if ((error = src_process(obj->write.src_state, &(obj->write.data))) != 0)
g_warning("error while samplerate conversion. error: %s", src_strerror(error));
obj->write.can_process = FALSE;
bytes = jack_ringbuffer_write (obj->write.buffer, (void *) obj->write.data.data_out, sizeof(sample_t)*obj->write.data.output_frames_gen);
obj->write.can_process = TRUE;
return bytes;
}
void jack_card_set_level(JackCard *obj,gint way,gint a)
{
switch(way){
case SND_CARD_LEVEL_GENERAL:
obj->level = (float)a / 100.0;
break;
case SND_CARD_LEVEL_INPUT:
obj->read.level = (float)a / 100.0;
break;
case SND_CARD_LEVEL_OUTPUT:
obj->write.level = (float)a / 100.0;
break;
default:
g_warning("jack_card_set_level: unsupported command.");
}
}
gint jack_card_get_level(JackCard *obj,gint way)
{
gint value = 0;
switch(way){
case SND_CARD_LEVEL_GENERAL:
value = (gint)(obj->level*100.0);
break;
case SND_CARD_LEVEL_INPUT:
value = (gint)(obj->read.level*100.0);
break;
case SND_CARD_LEVEL_OUTPUT:
value = (gint)(obj->write.level*100.0);
break;
default:
g_warning("jack_card_get_level: unsupported command.");
}
return value;
}
void jack_card_set_source(JackCard *obj,int source)
{
}
MSFilter *jack_card_create_read_filter(JackCard *card)
{
MSFilter *f=ms_oss_read_new();
ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index);
return f;
}
MSFilter *jack_card_create_write_filter(JackCard *card)
{
MSFilter *f=ms_oss_write_new();
ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index);
return f;
}
SndCard * jack_card_new(jack_client_t *client)
{
JackCard * obj;
SndCard *base;
obj= g_new0(JackCard,1);
if (!client) return NULL;
obj->client = client;
obj->jack_running = TRUE;
obj->jack_active = FALSE;
obj->can_process = FALSE;
obj->clear = TRUE;
obj->write.can_process = FALSE;
obj->write.open = FALSE;
obj->write.init = TRUE;
obj->write.port = NULL;
obj->write.phys_ports = NULL;
obj->write.buffer = NULL;
obj->read.can_process = FALSE;
obj->read.open = FALSE;
obj->read.init = TRUE;
obj->read.port = NULL;
obj->read.phys_ports = NULL;
obj->read.buffer = NULL;
/* tell the JACK server to call `process()' whenever
there is work to be done.
*/
jack_set_process_callback (client, process, obj);
/* tell the JACK server to call `jack_shutdown()' if
it ever shuts down, either entirely, or if it
just decides to stop calling us.
*/
jack_on_shutdown (client, jack_shutdown, obj);
jack_set_sample_rate_callback (client, samplerate, obj);
obj->rate = jack_get_sample_rate (client);
obj->buffer_size = jack_get_buffer_size(obj->client);
jack_init(obj);
base= SND_CARD(obj);
snd_card_init(base);
#ifdef HAVE_GLIB
base->card_name=g_strdup_printf("JACK client");
#else
base->card_name=malloc(100);
snprintf(base->card_name, 100, "JACK client");
#endif
base->_probe=(SndCardOpenFunc)jack_card_probe;
base->_open_r=(SndCardOpenFunc)jack_card_open_r;
base->_open_w=(SndCardOpenFunc)jack_card_open_w;
base->_can_read=(SndCardPollFunc)jack_card_can_read;
base->_set_blocking_mode=(SndCardSetBlockingModeFunc)jack_card_set_blocking_mode;
base->_read=(SndCardIOFunc)jack_card_read;
base->_write=(SndCardIOFunc)jack_card_write;
base->_close_r=(SndCardCloseFunc)jack_card_close_r;
base->_close_w=(SndCardCloseFunc)jack_card_close_w;
base->_set_rec_source=(SndCardMixerSetRecSourceFunc)jack_card_set_source;
base->_set_level=(SndCardMixerSetLevelFunc)jack_card_set_level;
base->_get_level=(SndCardMixerGetLevelFunc)jack_card_get_level;
base->_destroy=(SndCardDestroyFunc)jack_card_destroy;
base->_create_read_filter=(SndCardCreateFilterFunc)jack_card_create_read_filter;
base->_create_write_filter=(SndCardCreateFilterFunc)jack_card_create_write_filter;
obj->read.buffer=NULL;
obj->write.buffer=NULL;
obj->buffer_size = 0;
obj->level = 1.0;
obj->write.level = 1.0;
obj->read.level = 1.0;
return base;
}
gint jack_card_manager_init(SndCardManager *m, gint index)
{
jack_client_t *client = NULL;
char* client_name;
client_name=g_strdup_printf("linphone-%u", g_random_int());
if ((client = jack_client_new (client_name))!= NULL)
{
g_message("Found Jack Daemon");
g_free(client_name);
m->cards[index]=jack_card_new(client);
m->cards[index]->index=index;
return 1;
} else {
g_free(client_name);
return 0;
}
}
#endif

View file

@ -1,81 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
JACK support
Copyright (C) 2004 Tobias Gehrig tobias@gehrig.tk
*/
#ifndef JACK_CARD_H
#define JACK_CARD_H
#include <config.h>
#ifdef __JACK_ENABLED__
#include "sndcard.h"
#include <jack/jack.h>
#include <jack/ringbuffer.h>
#include <samplerate.h>
typedef jack_default_audio_sample_t sample_t;
typedef struct {
jack_port_t *port;
const char **phys_ports;
float level;
jack_ringbuffer_t *buffer;
gint channels;
gint rate;
SRC_STATE* src_state;
SRC_DATA data;
size_t frames;
gboolean can_process;
gboolean open;
gboolean init;
} jackcard_mode_t;
struct _JackCard
{
SndCard parent;
jack_client_t *client;
gboolean jack_running;
gboolean jack_active;
float level;
jack_nframes_t buffer_size;
gint sample_size;
gint frame_size;
gint rate;
gboolean can_process;
gboolean clear;
jackcard_mode_t read, write;
};
typedef struct _JackCard JackCard;
SndCard * jack_card_new(jack_client_t *client);
gint jack_card_manager_init(SndCardManager *m, gint index);
#endif
#endif

View file

@ -1,144 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mediastream.h"
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int cond=1;
void stop_handler(int signum)
{
cond--;
if (cond<0) exit(-1);
}
void parse_addr(gchar *addr, char **ip, int *port)
{
char *semicolon;
gint iplen;
*ip=NULL;
*port=0;
semicolon=strchr(addr,':');
if (semicolon==NULL) return;
iplen=semicolon-addr;
*ip=g_malloc(iplen+1);
strncpy(*ip,addr,iplen);
(*ip)[iplen]='\0';
*port=atoi(semicolon+1);
}
char *usage="mediastream --local <port> --remote <ip:port> --payload <payload type number>\n";
void run_media_streams(gint localport, gchar *remote_ip, gint remoteport, gint payload);
int main(int argc, char * argv[])
{
gint i;
gint localport=0,remoteport=0,payload=0;
gchar *ip;
gchar *tmp;
/*create the rtp session */
ortp_init();
rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015);
rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb);
rtp_profile_set_payload(&av_profile,98,&payload_type_h263_1998);
if (argc<4) {
printf(usage);
return -1;
}
for (i=1;i<argc;i++){
if (strcmp(argv[i],"--local")==0){
i++;
localport=atoi(argv[i]);
}else if (strcmp(argv[i],"--remote")==0){
i++;
parse_addr(argv[i],&ip,&remoteport);
if (ip==NULL) {
printf(usage);
return -1;
}
printf("Remote addr: ip=%s port=%i\n",ip,remoteport);
}else if (strcmp(argv[i],"--payload")==0){
i++;
payload=atoi(argv[i]);
}
}
tmp=getenv("defcard");
if (tmp!=NULL) audio_stream_set_default_card(atoi(tmp));
run_media_streams(localport,ip,remoteport,payload);
return 0;
}
void run_media_streams(gint localport, gchar *remote_ip, gint remoteport, gint payload)
{
AudioStream *audio=NULL;
#ifdef VIDEO_ENABLED
VideoStream *video=NULL;
#endif
PayloadType *pt=rtp_profile_get_payload(&av_profile,payload);
if (pt==NULL) {
printf("Error: No payload type defined for %i !\n",payload);
exit (-1);
}
ms_init();
ms_speex_codec_init();
signal(SIGINT,stop_handler);
if (pt->type!=PAYLOAD_VIDEO){
printf("Starting audio stream.\n");
audio=audio_stream_start(&av_profile,localport,remote_ip,remoteport,payload,50);
}else{
#ifdef VIDEO_ENABLED
printf("Starting video stream.\n");
video=video_stream_start(&av_profile,
localport,
remote_ip,
remoteport,
payload,
50,
TRUE,
"Video4Linux",
"/dev/video0");
#else
printf("Error: video support not compiled.\n");
#endif
}
while(cond)
{
/* sleep until we receive SIGINT */
sleep(1);
ortp_global_stats_display();
}
printf("stoping all...\n");
if (audio) audio_stream_stop(audio);
#ifdef VIDEO_ENABLED
if (video) video_stream_stop(video);
#endif
}

View file

@ -1,133 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MEDIASTREAM_H
#define MEDIASTREAM_H
#include "msrtprecv.h"
#include "msrtpsend.h"
#include "ms.h"
#include "msosswrite.h"
#include "msossread.h"
#include "msread.h"
#include "mswrite.h"
#include "mstimer.h"
#include "mscodec.h"
#include "msspeexdec.h"
#include "msringplayer.h"
struct _AudioStream
{
MSSync *timer;
RtpSession *send_session;
RtpSession *recv_session;
MSFilter *soundread;
MSFilter *soundwrite;
MSFilter *encoder;
MSFilter *decoder;
MSFilter *rtprecv;
MSFilter *rtpsend;
};
typedef struct _AudioStream AudioStream;
struct _RingStream
{
MSSync *timer;
MSFilter *source;
MSFilter *sndwrite;
};
typedef struct _RingStream RingStream;
/* start a thread that does sampling->encoding->rtp_sending|rtp_receiving->decoding->playing */
AudioStream *audio_stream_start (RtpProfile * prof, int locport, char *remip,
int remport, int profile, int jitt_comp);
AudioStream *audio_stream_start_with_sndcards(RtpProfile * prof, int locport, char *remip4,
int remport, int profile, int jitt_comp, SndCard *playcard, SndCard *captcard);
AudioStream *audio_stream_start_with_files (RtpProfile * prof, int locport,
char *remip4, int remport,
int profile, int jitt_comp,
gchar * infile, gchar * outfile);
void audio_stream_set_rtcp_information(AudioStream *st, const char *cname);
/* stop the above process*/
void audio_stream_stop (AudioStream * stream);
RingStream *ring_start (gchar * file, gint interval, SndCard *sndcard);
RingStream *ring_start_with_cb(gchar * file, gint interval, SndCard *sndcard, MSFilterNotifyFunc func,gpointer user_data);
void ring_stop (RingStream * stream);
/* returns the latency in samples if the audio device with id dev_id is openable in full duplex mode, else 0 */
gint test_audio_dev (int dev_id);
/* send a dtmf */
gint audio_stream_send_dtmf (AudioStream * stream, gchar dtmf);
void audio_stream_set_default_card(int cardindex);
#ifdef VIDEO_ENABLED
/*****************
Video Support
*****************/
struct _VideoStream
{
MSSync *timer;
RtpSession *send_session;
RtpSession *recv_session;
MSFilter *source;
MSFilter *output;
MSFilter *encoder;
MSFilter *decoder;
MSFilter *rtprecv;
MSFilter *rtpsend;
gboolean show_local;
};
typedef struct _VideoStream VideoStream;
VideoStream *video_stream_start(RtpProfile *profile, int locport, char *remip4, int remport,
int payload, int jitt_comp, gboolean show_local, const gchar *source, const gchar *device);
void video_stream_set_rtcp_information(VideoStream *st, const char *cname);
void video_stream_stop (VideoStream * stream);
VideoStream * video_preview_start(const gchar *source, const gchar *device);
void video_preview_stop(VideoStream *stream);
VideoStream * video_stream_send_only_start(RtpProfile *profile, int locport, char *remip, int remport,
int payload, const gchar *source, const gchar *device);
void video_stream_send_only_stop(VideoStream *stream);
#endif
#endif

View file

@ -1,394 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; 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 "ms.h"
#include "sndcard.h"
#include "mscodec.h"
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#ifdef HAVE_DLOPEN
#include <dlfcn.h>
#endif
#ifdef HAVE_GLIB
#include "gmodule.h" /* g_module_open() */
#endif
#define MS_PLUGINS_DIR PACKAGE_PLUGINS_DIR "/mediastreamer"
#ifdef VIDEO_ENABLED
extern void ms_video_source_register_all();
#endif
/**
* ms_init:
*
*
* Initialize the mediastreamer. This must be the first function called in a program
* using the mediastreamer library.
*
*
*/
void ms_init()
{
if (!g_thread_supported()) g_thread_init (NULL);
/* initialize the oss subsystem */
snd_card_manager_init(snd_card_manager);
/* register the statically linked codecs */
ms_codec_register_all();
#ifdef VIDEO_ENABLED
ms_video_source_register_all();
#endif
ms_load_plugins(MS_PLUGINS_DIR);
}
static gint compare(gconstpointer a, gconstpointer b)
{
MSFilter *f1=(MSFilter*)a,*f2=(MSFilter*)b;
if (f1->klass<f2->klass) return -1;
if (f1->klass==f2->klass) return 0;
/* if f1->klass>f2->klass ....*/
return 1;
}
static GList *g_list_append_if_new(GList *l,gpointer data)
{
GList *res=l;
if (g_list_find(res,data)==NULL)
res=g_list_append(res,data);
return(res);
}
static GList *get_nexts(MSFilter *f,GList *l)
{
int i;
MSFifo *fifo;
MSQueue *q;
GList *res=l;
/* check fifos*/
for (i=0;i <f->klass->max_foutputs;i++)
{
fifo=f->outfifos[i];
if (fifo!=NULL) res=g_list_append_if_new(res,(gpointer)fifo->next_data);
}
/* check queues*/
for (i=0;i <f->klass->max_qoutputs;i++)
{
q=f->outqueues[i];
if (q!=NULL) res=g_list_append_if_new(res,(gpointer)q->next_data);
}
return(res);
}
/* compile graphs attached to a sync source*/
int ms_compile(MSSync *sync)
{
int i;
GList *list1=NULL,*list2=NULL,*elem;
GList *proc_chain=NULL;
MSFilter *f;
/* first free the old list if we are just updating*/
if (sync->execution_list!=NULL) g_list_free(sync->execution_list);
/* get the list of filters attached to this sync*/
for (i=0;i<sync->filters;i++)
{
//printf("found filter !\n");
list1=g_list_append(list1,sync->attached_filters[i]);
}
/* find the processing chain */
while (list1!=NULL)
{
list2=NULL;
/* sort the list by types of filter*/
list1=g_list_sort(list1,compare);
/* save into the processing chain list*/
//printf("list1 :%i elements\n",g_list_length(list1));
proc_chain=g_list_concat(proc_chain,list1);
/* get all following filters. They are appended to list2*/
elem=list1;
while (elem!=NULL)
{
f=(MSFilter*)(elem->data);
/* check if filter 's status */
if (f->klass->attributes & FILTER_CAN_SYNC)
{
sync->samples_per_tick=0;
}
list2=get_nexts(f,list2);
elem=g_list_next(elem);
}
list1=list2;
}
sync->execution_list=proc_chain;
sync->flags&=~MS_SYNC_NEED_UPDATE;
ms_trace("%i filters successfully compiled in a processing chain.",g_list_length(sync->execution_list));
return 0;
}
/*execute the processing chain attached to a sync source. It is called as a thread by ms_main()*/
void *ms_thread_run(void *sync_ptr)
{
MSSync *sync=(MSSync*) sync_ptr;
GList *filter;
MSFilter *f;
ms_sync_lock(sync);
while(sync->run)
{
//g_message("sync->run=%i",sync->run);
if (sync->samples_per_tick==0) ms_sync_suspend(sync);
if (sync->flags & MS_SYNC_NEED_UPDATE){
ms_compile(sync);
ms_sync_setup(sync);
}
filter=sync->execution_list;
ms_sync_unlock(sync);
//ms_trace("Calling synchronisation");
ms_sync_synchronize(sync);
while(filter!=NULL)
{
f=(MSFilter*)filter->data;
if (MS_FILTER_GET_CLASS(f)->attributes & FILTER_IS_SOURCE)
{
/* execute it once */
ms_trace("Running source filter %s.",f->klass->name);
ms_filter_process(f);
}
else
{
/* make the filter process its input data until it has no more */
while ( ms_filter_fifos_have_data(f) || ms_filter_queues_have_data(f) )
{
ms_trace("Running filter %s.",f->klass->name);
ms_filter_process(f);
}
}
filter=g_list_next(filter);
}
ms_sync_lock(sync);
}
g_cond_signal(sync->stop_cond); /* signal that the sync thread has finished */
ms_sync_unlock(sync);
g_message("Mediastreamer processing thread is exiting.");
return NULL;
}
/* stop the processing chain attached to a sync source.*/
void ms_thread_stop(MSSync *sync)
{
if (sync->thread!=NULL)
{
if (sync->samples_per_tick==0)
{
/* to wakeup the thread */
//g_cond_signal(sync->thread_cond);
}
g_mutex_lock(sync->lock);
sync->run=0;
sync->thread=NULL;
g_cond_wait(sync->stop_cond,sync->lock);
g_mutex_unlock(sync->lock);
}
//g_message("ms_thread_stop() finished.");
}
/**
* ms_start:
* @sync: A synchronisation source to be started.
*
* Starts a thread that will shedule all processing chains attached to the synchronisation source @sync.
*
*
*/
void ms_start(MSSync *sync)
{
if (sync->run==1) return; /*already running*/
ms_compile(sync);
ms_sync_setup(sync);
/* this is to avoid race conditions, for example:
ms_start(sync);
ms_oss_write_start(ossw);
here tge ossw filter need to be compiled to run ms_oss_write_start()
*/
ms_trace("ms_start: creating new thread.");
sync->run=1;
sync->thread=g_thread_create((GThreadFunc)ms_thread_run,(gpointer)sync,TRUE,NULL);
if (sync->thread==NULL){
g_warning("Could not create thread !");
}
}
/**
* ms_stop:
* @sync: A synchronisation source to be stopped.
*
* Stop the thread that was sheduling the processing chains attached to the synchronisation source @sync.
* The processing chains are kept unchanged, no object is freed. The synchronisation source can be restarted using ms_start().
*
*
*/
void ms_stop(MSSync *sync)
{
ms_thread_stop(sync);
ms_sync_unsetup(sync);
}
gint ms_load_plugin(gchar *path)
{
#ifdef HAVE_GLIB
g_module_open(path,0);
#endif
return 0;
}
gchar * ms_proc_get_param(gchar *parameter)
{
gchar *file;
int fd;
int err,len;
gchar *p,*begin,*end;
gchar *ret;
fd=open("/proc/cpuinfo",O_RDONLY);
if (fd<0){
g_warning("Could not open /proc/cpuinfo.");
return NULL;
}
file=g_malloc(1024);
err=read(fd,file,1024);
file[err-1]='\0';
/* find the parameter */
p=strstr(file,parameter);
if (p==NULL){
/* parameter not found */
g_free(file);
return NULL;
}
/* find the following ':' */
p=strchr(p,':');
if (p==NULL){
g_free(file);
return NULL;
}
/* find the value*/
begin=p+2;
end=strchr(begin,'\n');
if (end==NULL) end=strchr(begin,'\0');
len=end-begin+1;
ret=g_malloc(len+1);
snprintf(ret,len,"%s",begin);
//printf("%s=%s\n",parameter,ret);
g_free(file);
return ret;
}
gint ms_proc_get_type()
{
static int proc_type=0;
gchar *value;
if (proc_type==0){
value=ms_proc_get_param("cpu family");
if (value!=NULL) {
proc_type=atoi(value);
g_free(value);
}else return -1;
}
return proc_type;
}
gint ms_proc_get_speed()
{
char *value;
static int proc_speed=0;
if (proc_speed==0){
value=ms_proc_get_param("cpu MHz");
if (value!=NULL){
proc_speed=atoi(value);
g_free(value);
}else return -1;
}
//printf("proc_speed=%i\n",proc_speed);
return proc_speed;
}
#define PLUGINS_EXT ".so"
typedef void (*init_func_t)(void);
void ms_load_plugins(const char *dir){
#ifdef HAVE_DLOPEN
DIR *ds;
struct dirent *de;
char *fullpath;
ds=opendir(dir);
if (ds==NULL){
g_warning("Cannot open directory %s: %s",dir,strerror(errno));
return;
}
while( (de=readdir(ds))!=NULL){
if (de->d_type==DT_REG && strstr(de->d_name,PLUGINS_EXT)!=NULL){
void *handle;
fullpath=g_strdup_printf("%s/%s",dir,de->d_name);
g_message("Loading plugin %s...",fullpath);
if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){
g_warning("Fail to load plugin %s : %s",fullpath,dlerror());
}else {
char *initroutine_name=g_malloc0(strlen(de->d_name)+10);
char *p;
void *initroutine;
strcpy(initroutine_name,de->d_name);
p=strstr(initroutine_name,PLUGINS_EXT);
strcpy(p,"_init");
initroutine=dlsym(handle,initroutine_name);
if (initroutine!=NULL){
init_func_t func=(init_func_t)initroutine;
func();
g_message("Plugin loaded.");
}else{
g_warning("Could not locate init routine of plugin %s",de->d_name);
}
g_free(initroutine_name);
}
g_free(fullpath);
}
}
closedir(ds);
#else
g_warning("no loadable plugin support: plugins cannot be loaded.");
#endif
}

View file

@ -1,81 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MS_H
#define MS_H
#include "msfilter.h"
#include "mssync.h"
void ms_init();
/* compile graphs attached to a sync source*/
int ms_compile(MSSync *source);
/* stop the processing chain attached to a sync source.*/
void ms_thread_stop(MSSync *sync);
/**
* function_name:ms_thread_run
* @sync: The synchronization source for all the set of graphs to run.
*
* Execute the processing chain attached to a sync source. This function loops indefinitely.
* The media streamer programmer can choose to execute this function directly, or to call ms_start(),
* that will start a thread for the synchronisation source.
*
* Returns: no return value.
*/
void *ms_thread_run(void *sync);
/**
* function_name:ms_start
* @sync: A synchronisation source to be started.
*
* Starts a thread that will shedule all processing chains attached to the synchronisation source @sync.
*
* Returns: no return value.
*/
void ms_start(MSSync *sync);
/**
* function_name:ms_stop
* @sync: A synchronisation source to be stopped.
*
* Stop the thread that was sheduling the processing chains attached to the synchronisation source @sync.
* The processing chains are kept unchanged, no object is freed. The synchronisation source can be restarted using ms_start().
*
* Returns: no return value.
*/
void ms_stop(MSSync *sync);
gchar * ms_proc_get_param(gchar *parameter);
gint ms_proc_get_type();
gint ms_proc_get_speed();
void ms_load_plugins(const char *dir);
#endif

View file

@ -1,132 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msAlawdec.h"
#include "g711common.h"
extern MSFilter * ms_ALAWencoder_new(void);
MSCodecInfo ALAWinfo={
{
"ALAW codec",
0,
MS_FILTER_AUDIO_CODEC,
ms_ALAWencoder_new,
"This is the classic A-law codec. Good quality, but only usable with high speed network connections."
},
ms_ALAWencoder_new,
ms_ALAWdecoder_new,
320,
160,
64000,
8000,
8,
"PCMA",
1,
1,
};
static MSALAWDecoderClass *ms_ALAWdecoder_class=NULL;
MSFilter * ms_ALAWdecoder_new(void)
{
MSALAWDecoder *r;
r=g_new(MSALAWDecoder,1);
ms_ALAWdecoder_init(r);
if (ms_ALAWdecoder_class==NULL)
{
ms_ALAWdecoder_class=g_new(MSALAWDecoderClass,1);
ms_ALAWdecoder_class_init(ms_ALAWdecoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ALAWdecoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_ALAWdecoder_init(MSALAWDecoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=ALAW_DECODER_RMAXGRAN;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSALAWDECODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSALAWDECODER_MAX_INPUTS);
}
void ms_ALAWdecoder_class_init(MSALAWDecoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ALAWDecoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&ALAWinfo;
MS_FILTER_CLASS(klass)->max_finputs=MSALAWDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSALAWDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=ALAW_DECODER_RMAXGRAN;
MS_FILTER_CLASS(klass)->w_maxgran=ALAW_DECODER_WMAXGRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ALAWdecoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ALAWdecoder_process;
}
void ms_ALAWdecoder_process(MSALAWDecoder *r)
{
MSFifo *fi,*fo;
int inlen,outlen;
gchar *s,*d;
int i;
/* process output fifos, but there is only one for this class of filter*/
/* this is the simplest process function design:
the filter declares a r_mingran of ALAW_DECODER_RMAXGRAN, so the mediastreamer's
scheduler will call the process function each time there is ALAW_DECODER_RMAXGRAN
bytes to read in the input fifo. If there is more, then it will call it several
time in order to the fifo to be completetly processed.
This is very simple, but not very efficient because of the multiple call function
of MSFilterProcessFunc that may happen.
The MSAlawEncoder implements another design; see it.
*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
g_return_if_fail(fi!=NULL);
g_return_if_fail(fo!=NULL);
inlen=ms_fifo_get_read_ptr(fi,ALAW_DECODER_RMAXGRAN,(void**)&s);
if (s==NULL) return;
outlen=ms_fifo_get_write_ptr(fo,ALAW_DECODER_WMAXGRAN,(void**)&d);
if (d!=NULL)
{
for(i=0;i<ALAW_DECODER_RMAXGRAN;i++)
{
((gint16*)d)[i]=alaw_to_s16( (unsigned char) s[i]);
}
}
else g_warning("MSALAWDecoder: Discarding samples !!");
}
void ms_ALAWdecoder_destroy( MSALAWDecoder *obj)
{
g_free(obj);
}

View file

@ -1,65 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSALAWDECODER_H
#define MSALAWDECODER_H
#include "msfilter.h"
#include "mscodec.h"
/*this is the class that implements a ALAWdecoder filter*/
#define MSALAWDECODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSALAWDecoder
{
/* the MSALAWDecoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSALAWDecoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSALAWDECODER_MAX_INPUTS];
MSFifo *f_outputs[MSALAWDECODER_MAX_INPUTS];
} MSALAWDecoder;
typedef struct _MSALAWDecoderClass
{
/* the MSALAWDecoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSALAWDecoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSALAWDecoderClass;
/* PUBLIC */
#define MS_ALAWDECODER(filter) ((MSALAWDecoder*)(filter))
#define MS_ALAWDECODER_CLASS(klass) ((MSALAWDecoderClass*)(klass))
MSFilter * ms_ALAWdecoder_new(void);
/* FOR INTERNAL USE*/
void ms_ALAWdecoder_init(MSALAWDecoder *r);
void ms_ALAWdecoder_class_init(MSALAWDecoderClass *klass);
void ms_ALAWdecoder_destroy( MSALAWDecoder *obj);
void ms_ALAWdecoder_process(MSALAWDecoder *r);
/* tuning parameters :*/
#define ALAW_DECODER_WMAXGRAN 320
#define ALAW_DECODER_RMAXGRAN 160
extern MSCodecInfo ALAWinfo;
#endif

View file

@ -1,124 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msAlawenc.h"
#include "g711common.h"
extern MSCodecInfo ALAWinfo;
static MSALAWEncoderClass *ms_ALAWencoder_class=NULL;
MSFilter * ms_ALAWencoder_new(void)
{
MSALAWEncoder *r;
r=g_new(MSALAWEncoder,1);
ms_ALAWencoder_init(r);
if (ms_ALAWencoder_class==NULL)
{
ms_ALAWencoder_class=g_new(MSALAWEncoderClass,1);
ms_ALAWencoder_class_init(ms_ALAWencoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ALAWencoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_ALAWencoder_init(MSALAWEncoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=ALAW_ENCODER_RMAXGRAN; /* the filter can be called as soon as there is
something to process */
memset(r->f_inputs,0,sizeof(MSFifo*)*MSALAWENCODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSALAWENCODER_MAX_INPUTS);
}
void ms_ALAWencoder_class_init(MSALAWEncoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ALAWEncoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&ALAWinfo;
MS_FILTER_CLASS(klass)->max_finputs=MSALAWENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSALAWENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=ALAW_ENCODER_RMAXGRAN;
MS_FILTER_CLASS(klass)->w_maxgran=ALAW_ENCODER_WMAXGRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ALAWencoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ALAWencoder_process;
}
void ms_ALAWencoder_process(MSALAWEncoder *r)
{
MSFifo *fi,*fo;
int inlen,outlen;
gchar *s,*d;
int i;
/* process output fifos, but there is only one for this class of filter*/
/* this is the sophisticated design of the process function:
Here the filter declares that it can be called as soon as there is something
to read on the input fifo by setting r_mingran=0.
Then it ask for the fifo to get as many data as possible by calling:
inlen=ms_fifo_get_read_ptr(fi,0,(void**)&s);
This avoid multiple call to the process function to process all data available
on the input fifo... but the writing of the process function is a bit
more difficult, because althoug ms_fifo_get_read_ptr() returns N bytes,
we cannot ask ms_fifo_get_write_ptr to return N bytes if
N>MS_FILTER_CLASS(klass)->w_maxgran. This is forbidden by the MSFifo
mechanism.
This is an open issue.
For the moment what is done here is that ms_fifo_get_write_ptr() is called
several time with its maximum granularity in order to try to write the output.
...
One solution:
-create a new function ms_fifo_get_rw_ptr(fifo1,p1, fifo2,p2) to
return the number of bytes able to being processed according to the input
and output fifo, and their respective data pointers
*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
inlen=ms_fifo_get_read_ptr(fi,ALAW_ENCODER_RMAXGRAN,(void**)&s);
if (s==NULL) return;
outlen=ms_fifo_get_write_ptr(fo,ALAW_ENCODER_WMAXGRAN,(void**)&d);
if (d!=NULL)
{
for(i=0;i<ALAW_ENCODER_WMAXGRAN;i++)
{
d[i]=s16_to_alaw( *((gint16*)s) );
s+=2;
}
}
else g_warning("MSALAWDecoder: Discarding samples !!");
}
void ms_ALAWencoder_destroy( MSALAWEncoder *obj)
{
g_free(obj);
}

View file

@ -1,64 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSALAWENCODER_H
#define MSALAWENCODER_H
#include "mscodec.h"
/*this is the class that implements a ALAWencoder filter*/
#define MSALAWENCODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSALAWEncoder
{
/* the MSALAWEncoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSALAWEncoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSALAWENCODER_MAX_INPUTS];
MSFifo *f_outputs[MSALAWENCODER_MAX_INPUTS];
} MSALAWEncoder;
typedef struct _MSALAWEncoderClass
{
/* the MSALAWEncoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSALAWEncoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSALAWEncoderClass;
/* PUBLIC */
#define MS_ALAWENCODER(filter) ((MSALAWEncoder*)(filter))
#define MS_ALAWENCODER_CLASS(klass) ((MSALAWEncoderClass*)(klass))
MSFilter * ms_ALAWencoder_new(void);
/* FOR INTERNAL USE*/
void ms_ALAWencoder_init(MSALAWEncoder *r);
void ms_ALAWencoder_class_init(MSALAWEncoderClass *klass);
void ms_ALAWencoder_destroy( MSALAWEncoder *obj);
void ms_ALAWencoder_process(MSALAWEncoder *r);
/* tuning parameters :*/
#define ALAW_ENCODER_WMAXGRAN 160
#define ALAW_ENCODER_RMAXGRAN 320
#endif

View file

@ -1,116 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msGSMdecoder.h"
extern MSFilter * ms_GSMencoder_new(void);
MSCodecInfo GSMinfo={
{
"GSM codec",
0,
MS_FILTER_AUDIO_CODEC,
ms_GSMencoder_new,
"This is the codec widely used in european mobile phones. This implementation was done by "
"Jutta Degener and Carsten Bormann."
},
ms_GSMencoder_new,
ms_GSMdecoder_new,
320,
33,
13800,
8000,
3,
"GSM",
1,
1,
};
static MSGSMDecoderClass *ms_GSMdecoder_class=NULL;
MSFilter * ms_GSMdecoder_new(void)
{
MSGSMDecoder *r;
r=g_new(MSGSMDecoder,1);
ms_GSMdecoder_init(r);
if (ms_GSMdecoder_class==NULL)
{
ms_GSMdecoder_class=g_new(MSGSMDecoderClass,1);
ms_GSMdecoder_class_init(ms_GSMdecoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_GSMdecoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_GSMdecoder_init(MSGSMDecoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->inqueues=r->q_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=33;
memset(r->q_inputs,0,sizeof(MSFifo*)*MSGSMDECODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSGSMDECODER_MAX_INPUTS);
r->gsm_handle=gsm_create();
}
void ms_GSMdecoder_class_init(MSGSMDecoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"GSMDecoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&GSMinfo;
MS_FILTER_CLASS(klass)->max_qinputs=MSGSMDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSGSMDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->w_maxgran=2*160;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_GSMdecoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_GSMdecoder_process;
}
void ms_GSMdecoder_process(MSGSMDecoder *r)
{
MSFifo *fo;
MSQueue *qi;
void *d;
MSMessage *inm;
/* process output fifos, but there is only one for this class of filter*/
qi=r->q_inputs[0];
fo=r->f_outputs[0];
inm=ms_queue_get(qi);
ms_fifo_get_write_ptr(fo,160*2,&d);
if (d!=NULL)
gsm_decode(r->gsm_handle,(guchar*)inm->data,(gsm_signal*)d);
ms_message_destroy(inm);
}
void ms_GSMdecoder_uninit(MSGSMDecoder *obj)
{
gsm_destroy(obj->gsm_handle);
}
void ms_GSMdecoder_destroy( MSGSMDecoder *obj)
{
ms_GSMdecoder_uninit(obj);
g_free(obj);
}

View file

@ -1,64 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSGSMDECODER_H
#define MSGSMDECODER_H
#include "msfilter.h"
#include "mscodec.h"
#include <gsm.h>
/*this is the class that implements a GSMdecoder filter*/
#define MSGSMDECODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSGSMDecoder
{
/* the MSGSMDecoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSGSMDecoder object
in order to the object mechanism to work*/
MSFilter filter;
MSQueue *q_inputs[MSGSMDECODER_MAX_INPUTS];
MSFifo *f_outputs[MSGSMDECODER_MAX_INPUTS];
gsm gsm_handle;
} MSGSMDecoder;
typedef struct _MSGSMDecoderClass
{
/* the MSGSMDecoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSGSMDecoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSGSMDecoderClass;
/* PUBLIC */
#define MS_GSMDECODER(filter) ((MSGSMDecoder*)(filter))
#define MS_GSMDECODER_CLASS(klass) ((MSGSMDecoderClass*)(klass))
MSFilter * ms_GSMdecoder_new(void);
/* FOR INTERNAL USE*/
void ms_GSMdecoder_init(MSGSMDecoder *r);
void ms_GSMdecoder_class_init(MSGSMDecoderClass *klass);
void ms_GSMdecoder_destroy( MSGSMDecoder *obj);
void ms_GSMdecoder_process(MSGSMDecoder *r);
extern MSCodecInfo GSMinfo;
#endif

View file

@ -1,98 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msGSMencoder.h"
#include "mscodec.h"
extern MSCodecInfo GSMinfo;
static MSGSMEncoderClass *ms_GSMencoder_class=NULL;
MSFilter * ms_GSMencoder_new(void)
{
MSGSMEncoder *r;
r=g_new(MSGSMEncoder,1);
ms_GSMencoder_init(r);
if (ms_GSMencoder_class==NULL)
{
ms_GSMencoder_class=g_new(MSGSMEncoderClass,1);
ms_GSMencoder_class_init(ms_GSMencoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_GSMencoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_GSMencoder_init(MSGSMEncoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outqueues=r->q_outputs;
MS_FILTER(r)->r_mingran=2*160;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSGSMENCODER_MAX_INPUTS);
memset(r->q_outputs,0,sizeof(MSFifo*)*MSGSMENCODER_MAX_INPUTS);
r->gsm_handle=gsm_create();
}
void ms_GSMencoder_class_init(MSGSMEncoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"GSMEncoder");
MS_FILTER_CLASS(klass)->max_finputs=MSGSMENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_qoutputs=MSGSMENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=2*160;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_GSMencoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_GSMencoder_process;
MS_FILTER_CLASS(klass)->info=MS_FILTER_INFO(&GSMinfo);
}
void ms_GSMencoder_process(MSGSMEncoder *r)
{
MSFifo *fi;
MSQueue *qo;
int err1;
void *s;
/* process output fifos, but there is only one for this class of filter*/
fi=r->f_inputs[0];
qo=r->q_outputs[0];
err1=ms_fifo_get_read_ptr(fi,160*2,&s);
if (err1>0){
MSMessage *m=ms_message_new(33);
gsm_encode(r->gsm_handle,(gsm_signal*)s,(gsm_byte*)m->data);
ms_queue_put(qo,m);
}
}
void ms_GSMencoder_uninit(MSGSMEncoder *obj)
{
gsm_destroy(obj->gsm_handle);
}
void ms_GSMencoder_destroy( MSGSMEncoder *obj)
{
ms_GSMencoder_uninit(obj);
g_free(obj);
}

View file

@ -1,61 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSGSMENCODER_H
#define MSGSMENCODER_H
#include "msfilter.h"
#include <gsm.h>
/*this is the class that implements a GSMencoder filter*/
#define MSGSMENCODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSGSMEncoder
{
/* the MSGSMEncoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSGSMEncoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSGSMENCODER_MAX_INPUTS];
MSQueue *q_outputs[MSGSMENCODER_MAX_INPUTS];
gsm gsm_handle;
} MSGSMEncoder;
typedef struct _MSGSMEncoderClass
{
/* the MSGSMEncoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSGSMEncoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSGSMEncoderClass;
/* PUBLIC */
#define MS_GSMENCODER(filter) ((MSGSMEncoder*)(filter))
#define MS_GSMENCODER_CLASS(klass) ((MSGSMEncoderClass*)(klass))
MSFilter * ms_GSMencoder_new(void);
/* FOR INTERNAL USE*/
void ms_GSMencoder_init(MSGSMEncoder *r);
void ms_GSMencoder_class_init(MSGSMEncoderClass *klass);
void ms_GSMencoder_destroy( MSGSMEncoder *obj);
void ms_GSMencoder_process(MSGSMEncoder *r);
#endif

View file

@ -1,129 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msLPC10decoder.h"
#include "msLPC10encoder.h"
#include <stdlib.h>
#include <lpc10.h>
extern MSFilter * ms_LPC10encoder_new(void);
MSCodecInfo LPC10info={
{
"LPC10-15 codec",
0,
MS_FILTER_AUDIO_CODEC,
ms_LPC10encoder_new,
"A low quality but very low bit rate codec from the U.S. Department of Defense."
},
ms_LPC10encoder_new,
ms_LPC10decoder_new,
360,
7,
2400,
8000,
115,
"1015",
1,
1,
};
static MSLPC10DecoderClass *ms_LPC10decoder_class=NULL;
MSFilter * ms_LPC10decoder_new(void)
{
MSLPC10Decoder *r;
r=g_new(MSLPC10Decoder,1);
ms_LPC10decoder_init(r);
if (ms_LPC10decoder_class==NULL)
{
ms_LPC10decoder_class=g_new(MSLPC10DecoderClass,1);
ms_LPC10decoder_class_init(ms_LPC10decoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_LPC10decoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_LPC10decoder_init(MSLPC10Decoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=7;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSLPC10DECODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSLPC10DECODER_MAX_INPUTS);
r->lpc10_dec=create_lpc10_decoder_state();
}
void ms_LPC10decoder_class_init(MSLPC10DecoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"LPC10Dec");
MS_FILTER_CLASS(klass)->max_finputs=MSLPC10DECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSLPC10DECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=7;
MS_FILTER_CLASS(klass)->w_maxgran=LPC10_SAMPLES_PER_FRAME*2;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_LPC10decoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_LPC10decoder_process;
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&LPC10info;
}
void ms_LPC10decoder_process(MSLPC10Decoder *r)
{
MSFifo *fi,*fo;
int err1;
void *s,*d;
float speech[LPC10_SAMPLES_PER_FRAME];
INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
/* process output fifos, but there is only one for this class of filter*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
if (fi!=NULL)
{
err1=ms_fifo_get_read_ptr(fi,7,&s);
if (err1>0)
{
err1=ms_fifo_get_write_ptr(fo,LPC10_SAMPLES_PER_FRAME*2,&d);
if (d!=NULL)
{
read_bits(s, bits, LPC10_BITS_IN_COMPRESSED_FRAME);
lpc10_decode(bits,speech, r->lpc10_dec);
write_16bit_samples((INT16*)d, speech, LPC10_SAMPLES_PER_FRAME);
}
}
}
}
void ms_LPC10decoder_uninit(MSLPC10Decoder *obj)
{
free(obj->lpc10_dec);
}
void ms_LPC10decoder_destroy( MSLPC10Decoder *obj)
{
ms_LPC10decoder_uninit(obj);
g_free(obj);
}

View file

@ -1,64 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSLPC10DECODER_H
#define MSLPC10DECODER_H
#include <msfilter.h>
#include <mscodec.h>
#include <lpc10.h>
/*this is the class that implements a LPC10decoder filter*/
#define MSLPC10DECODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSLPC10Decoder
{
/* the MSLPC10Decoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSLPC10Decoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSLPC10DECODER_MAX_INPUTS];
MSFifo *f_outputs[MSLPC10DECODER_MAX_INPUTS];
struct lpc10_decoder_state *lpc10_dec;
} MSLPC10Decoder;
typedef struct _MSLPC10DecoderClass
{
/* the MSLPC10Decoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSLPC10Decoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSLPC10DecoderClass;
/* PUBLIC */
#define MS_LPC10DECODER(filter) ((MSLPC10Decoder*)(filter))
#define MS_LPC10DECODER_CLASS(klass) ((MSLPC10DecoderClass*)(klass))
MSFilter * ms_LPC10decoder_new(void);
/* FOR INTERNAL USE*/
void ms_LPC10decoder_init(MSLPC10Decoder *r);
void ms_LPC10decoder_class_init(MSLPC10DecoderClass *klass);
void ms_LPC10decoder_destroy( MSLPC10Decoder *obj);
void ms_LPC10decoder_process(MSLPC10Decoder *r);
extern MSCodecInfo LPC10info;
#endif

View file

@ -1,251 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include "msLPC10encoder.h"
#include <lpc10.h>
extern MSCodecInfo LPC10info;
/* The return value of each of these calls is the same as that
returned by fread/fwrite, which should be the number of samples
successfully read/written, not the number of bytes. */
int
read_16bit_samples(INT16 int16samples[], float speech[], int n)
{
int i;
/* Convert 16 bit integer samples to floating point values in the
range [-1,+1]. */
for (i = 0; i < n; i++) {
speech[i] = ((float) int16samples[i]) / 32768.0;
}
return (n);
}
int
write_16bit_samples(INT16 int16samples[], float speech[], int n)
{
int i;
float real_sample;
/* Convert floating point samples in range [-1,+1] to 16 bit
integers. */
for (i = 0; i < n; i++) {
real_sample = 32768.0 * speech[i];
if (real_sample < -32768.0) {
int16samples[i] = -32768;
} else if (real_sample > 32767.0) {
int16samples[i] = 32767;
} else {
int16samples[i] = real_sample;
}
}
return (n);
}
/*
Write the bits in bits[0] through bits[len-1] to file f, in "packed"
format.
bits is expected to be an array of len integer values, where each
integer is 0 to represent a 0 bit, and any other value represents a 1
bit. This bit string is written to the file f in the form of several
8 bit characters. If len is not a multiple of 8, then the last
character is padded with 0 bits -- the padding is in the least
significant bits of the last byte. The 8 bit characters are "filled"
in order from most significant bit to least significant.
*/
void
write_bits(unsigned char *data, INT32 *bits, int len)
{
int i; /* generic loop variable */
unsigned char mask; /* The next bit position within the
variable "data" to place the next
bit. */
/* Fill in the array bits.
* The first compressed output bit will be the most significant
* bit of the byte, so initialize mask to 0x80. The next byte of
* compressed data is initially 0, and the desired bits will be
* turned on below.
*/
mask = 0x80;
*data = 0;
for (i = 0; i < len; i++) {
/* Turn on the next bit of output data, if necessary. */
if (bits[i]) {
(*data) |= mask;
}
/*
* If the byte data is full, determined by mask becoming 0,
* then write the byte to the output file, and reinitialize
* data and mask for the next output byte. Also add the byte
* if (i == len-1), because if len is not a multiple of 8,
* then mask won't yet be 0. */
mask >>= 1;
if ((mask == 0) || (i == len-1)) {
data++;
*data = 0;
mask = 0x80;
}
}
}
/*
Read bits from file f into bits[0] through bits[len-1], in "packed"
format.
Read ceiling(len/8) characters from file f, if that many are available
to read, otherwise read to the end of the file. The first character's
8 bits, in order from MSB to LSB, are used to fill bits[0] through
bits[7]. The second character's bits are used to fill bits[8] through
bits[15], and so on. If ceiling(len/8) characters are available to
read, and len is not a multiple of 8, then some of the least
significant bits of the last character read are completely ignored.
Every entry of bits[] that is modified is changed to either a 0 or a
1.
The number of bits successfully read is returned, and is always in the
range 0 to len, inclusive. If it is less than len, it will always be
a multiple of 8.
*/
int
read_bits(unsigned char *data, INT32 *bits, int len)
{
int i,ind=0; /* generic loop variable */
int c=0;
/* Unpack the array bits into coded_frame. */
for (i = 0; i < len; i++) {
if ((i % 8) == 0) {
c = (int)(data[ind]);
ind++;
}
if (c & (0x80 >> (i & 7))) {
bits[i] = 1;
} else {
bits[i] = 0;
}
}
return (len);
}
static MSLPC10EncoderClass *ms_LPC10encoder_class=NULL;
MSFilter * ms_LPC10encoder_new(void)
{
MSLPC10Encoder *r;
r=g_new(MSLPC10Encoder,1);
ms_LPC10encoder_init(r);
if (ms_LPC10encoder_class==NULL)
{
ms_LPC10encoder_class=g_new(MSLPC10EncoderClass,1);
ms_LPC10encoder_class_init(ms_LPC10encoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_LPC10encoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_LPC10encoder_init(MSLPC10Encoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=LPC10_SAMPLES_PER_FRAME*2;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSLPC10ENCODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSLPC10ENCODER_MAX_INPUTS);
r->lpc10_enc=create_lpc10_encoder_state();
}
void ms_LPC10encoder_class_init(MSLPC10EncoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"LPC10Enc");
MS_FILTER_CLASS(klass)->max_finputs=MSLPC10ENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSLPC10ENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=LPC10_SAMPLES_PER_FRAME*2;
MS_FILTER_CLASS(klass)->w_maxgran=7;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_LPC10encoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_LPC10encoder_process;
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&LPC10info;
}
void ms_LPC10encoder_process(MSLPC10Encoder *r)
{
MSFifo *fi,*fo;
int err1;
void *s,*d;
float speech[LPC10_SAMPLES_PER_FRAME];
INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
/* process output fifos, but there is only one for this class of filter*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
if (fi!=NULL)
{
err1=ms_fifo_get_read_ptr(fi,LPC10_SAMPLES_PER_FRAME*2,&s);
if (err1>0)
{
err1=ms_fifo_get_write_ptr(fo,7,&d);
if (d!=NULL)
{
read_16bit_samples((INT16*)s, speech, LPC10_SAMPLES_PER_FRAME);
lpc10_encode(speech, bits, r->lpc10_enc);
write_bits(d, bits, LPC10_BITS_IN_COMPRESSED_FRAME);
}
}
}
}
void ms_LPC10encoder_uninit(MSLPC10Encoder *obj)
{
free(obj->lpc10_enc);
}
void ms_LPC10encoder_destroy( MSLPC10Encoder *obj)
{
ms_LPC10encoder_uninit(obj);
g_free(obj);
}

View file

@ -1,74 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSLPC10ENCODER_H
#define MSLPC10ENCODER_H
#include "mscodec.h"
int
read_16bit_samples(gint16 int16samples[], float speech[], int n);
int
write_16bit_samples(gint16 int16samples[], float speech[], int n);
void
write_bits(unsigned char *data, gint32 *bits, int len);
int
read_bits(unsigned char *data, gint32 *bits, int len);
/*this is the class that implements a LPC10encoder filter*/
#define MSLPC10ENCODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSLPC10Encoder
{
/* the MSLPC10Encoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSLPC10Encoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSLPC10ENCODER_MAX_INPUTS];
MSFifo *f_outputs[MSLPC10ENCODER_MAX_INPUTS];
struct lpc10_encoder_state *lpc10_enc;
} MSLPC10Encoder;
typedef struct _MSLPC10EncoderClass
{
/* the MSLPC10Encoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSLPC10Encoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSLPC10EncoderClass;
/* PUBLIC */
#define MS_LPC10ENCODER(filter) ((MSLPC10Encoder*)(filter))
#define MS_LPC10ENCODER_CLASS(klass) ((MSLPC10EncoderClass*)(klass))
MSFilter * ms_LPC10encoder_new(void);
/* FOR INTERNAL USE*/
void ms_LPC10encoder_init(MSLPC10Encoder *r);
void ms_LPC10encoder_class_init(MSLPC10EncoderClass *klass);
void ms_LPC10encoder_destroy( MSLPC10Encoder *obj);
void ms_LPC10encoder_process(MSLPC10Encoder *r);
#endif

View file

@ -1,130 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msMUlawdec.h"
#include "g711common.h"
extern MSFilter * ms_MULAWencoder_new(void);
MSCodecInfo MULAWinfo={
{
"MULAW codec",
0,
MS_FILTER_AUDIO_CODEC,
ms_MULAWencoder_new,
"This is the classic Mu-law codec. Good quality, but only usable with high speed network connections."
},
ms_MULAWencoder_new,
ms_MULAWdecoder_new,
320,
160,
64000,
8000,
0,
"PCMU",
1,
1
};
static MSMULAWDecoderClass *ms_MULAWdecoder_class=NULL;
MSFilter * ms_MULAWdecoder_new(void)
{
MSMULAWDecoder *r;
r=g_new(MSMULAWDecoder,1);
ms_MULAWdecoder_init(r);
if (ms_MULAWdecoder_class==NULL)
{
ms_MULAWdecoder_class=g_new(MSMULAWDecoderClass,1);
ms_MULAWdecoder_class_init(ms_MULAWdecoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_MULAWdecoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_MULAWdecoder_init(MSMULAWDecoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=MULAW_DECODER_RMAXGRAN;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSMULAWDECODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSMULAWDECODER_MAX_INPUTS);
}
void ms_MULAWdecoder_class_init(MSMULAWDecoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MULAWDecoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&MULAWinfo;
MS_FILTER_CLASS(klass)->max_finputs=MSMULAWDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSMULAWDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=MULAW_DECODER_RMAXGRAN;
MS_FILTER_CLASS(klass)->w_maxgran=MULAW_DECODER_WMAXGRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_MULAWdecoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_MULAWdecoder_process;
}
void ms_MULAWdecoder_process(MSMULAWDecoder *r)
{
MSFifo *fi,*fo;
int inlen,outlen;
gchar *s,*d;
int i;
/* process output fifos, but there is only one for this class of filter*/
/* this is the simplest process function design:
the filter declares a r_mingran of MULAW_DECODER_RMAXGRAN, so the mediastreamer's
scheduler will call the process function each time there is MULAW_DECODER_RMAXGRAN
bytes to read in the input fifo. If there is more, then it will call it several
time in order to the fifo to be completetly processed.
This is very simple, but not very efficient because of the multiple call function
of MSFilterProcessFunc that may happen.
The MSAlawEncoder implements another design; see it.
*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
inlen=ms_fifo_get_read_ptr(fi,MULAW_DECODER_RMAXGRAN,(void**)&s);
if (s==NULL) g_error("ms_MULAWdecoder_process: internal error.");
outlen=ms_fifo_get_write_ptr(fo,MULAW_DECODER_WMAXGRAN,(void**)&d);
if (d!=NULL)
{
for(i=0;i<MULAW_DECODER_RMAXGRAN;i++)
{
*((gint16*)d)=ulaw_to_s16( (unsigned char) s[i]);
d+=2;
}
}
else g_warning("MSMULAWDecoder: Discarding samples !!");
}
void ms_MULAWdecoder_destroy( MSMULAWDecoder *obj)
{
g_free(obj);
}

View file

@ -1,66 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSMULAWDECODER_H
#define MSMULAWDECODER_H
#include "msfilter.h"
#include "mscodec.h"
/*this is the class that implements a MULAWdecoder filter*/
#define MSMULAWDECODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSMULAWDecoder
{
/* the MSMULAWDecoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSMULAWDecoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSMULAWDECODER_MAX_INPUTS];
MSFifo *f_outputs[MSMULAWDECODER_MAX_INPUTS];
} MSMULAWDecoder;
typedef struct _MSMULAWDecoderClass
{
/* the MSMULAWDecoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSMULAWDecoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSMULAWDecoderClass;
/* PUBLIC */
#define MS_MULAWDECODER(filter) ((MSMULAWDecoder*)(filter))
#define MS_MULAWDECODER_CLASS(klass) ((MSMULAWDecoderClass*)(klass))
MSFilter * ms_MULAWdecoder_new(void);
/* FOR INTERNAL USE*/
void ms_MULAWdecoder_init(MSMULAWDecoder *r);
void ms_MULAWdecoder_class_init(MSMULAWDecoderClass *klass);
void ms_MULAWdecoder_destroy( MSMULAWDecoder *obj);
void ms_MULAWdecoder_process(MSMULAWDecoder *r);
/* tuning parameters :*/
#define MULAW_DECODER_WMAXGRAN 320
#define MULAW_DECODER_RMAXGRAN 160
extern MSCodecInfo MULAWinfo;
#endif

View file

@ -1,99 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msMUlawenc.h"
#include "g711common.h"
extern MSCodecInfo MULAWinfo;
static MSMULAWEncoderClass *ms_MULAWencoder_class=NULL;
MSFilter * ms_MULAWencoder_new(void)
{
MSMULAWEncoder *r;
r=g_new(MSMULAWEncoder,1);
ms_MULAWencoder_init(r);
if (ms_MULAWencoder_class==NULL)
{
ms_MULAWencoder_class=g_new(MSMULAWEncoderClass,1);
ms_MULAWencoder_class_init(ms_MULAWencoder_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_MULAWencoder_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_MULAWencoder_init(MSMULAWEncoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=MULAW_ENCODER_RMAXGRAN; /* the filter can be called as soon as there is
something to process */
memset(r->f_inputs,0,sizeof(MSFifo*)*MSMULAWENCODER_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSMULAWENCODER_MAX_INPUTS);
}
void ms_MULAWencoder_class_init(MSMULAWEncoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MULAWEncoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&MULAWinfo;
MS_FILTER_CLASS(klass)->max_finputs=MSMULAWENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSMULAWENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=MULAW_ENCODER_RMAXGRAN;
MS_FILTER_CLASS(klass)->w_maxgran=MULAW_ENCODER_WMAXGRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_MULAWencoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_MULAWencoder_process;
}
void ms_MULAWencoder_process(MSMULAWEncoder *r)
{
MSFifo *fi,*fo;
int inlen,outlen;
gchar *s,*d;
int i;
/* process output fifos, but there is only one for this class of filter*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
inlen=ms_fifo_get_read_ptr(fi,MULAW_ENCODER_RMAXGRAN,(void**)&s);
outlen=ms_fifo_get_write_ptr(fo,MULAW_ENCODER_WMAXGRAN,(void**)&d);
if (d!=NULL)
{
for(i=0;i<MULAW_ENCODER_WMAXGRAN;i++)
{
d[i]=s16_to_ulaw( *((gint16*)s) );
s+=2;
}
}
else g_warning("MSMULAWDecoder: Discarding samples !!");
}
void ms_MULAWencoder_destroy( MSMULAWEncoder *obj)
{
g_free(obj);
}

View file

@ -1,63 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSMULAWENCODER_H
#define MSMULAWENCODER_H
#include "mscodec.h"
/*this is the class that implements a MULAWencoder filter*/
#define MSMULAWENCODER_MAX_INPUTS 1 /* max output per filter*/
typedef struct _MSMULAWEncoder
{
/* the MSMULAWEncoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSMULAWEncoder object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSMULAWENCODER_MAX_INPUTS];
MSFifo *f_outputs[MSMULAWENCODER_MAX_INPUTS];
} MSMULAWEncoder;
typedef struct _MSMULAWEncoderClass
{
/* the MSMULAWEncoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSMULAWEncoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSMULAWEncoderClass;
/* PUBLIC */
#define MS_MULAWENCODER(filter) ((MSMULAWEncoder*)(filter))
#define MS_MULAWENCODER_CLASS(klass) ((MSMULAWEncoderClass*)(klass))
MSFilter * ms_MULAWencoder_new(void);
/* FOR INTERNAL USE*/
void ms_MULAWencoder_init(MSMULAWEncoder *r);
void ms_MULAWencoder_class_init(MSMULAWEncoderClass *klass);
void ms_MULAWencoder_destroy( MSMULAWEncoder *obj);
void ms_MULAWencoder_process(MSMULAWEncoder *r);
/* tuning parameters :*/
#define MULAW_ENCODER_WMAXGRAN 160
#define MULAW_ENCODER_RMAXGRAN 320
#endif

View file

@ -1,294 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include "msavdecoder.h"
#include "mscodec.h"
#include "rfc2429.h"
extern MSFilter *ms_mpeg_encoder_new();
extern MSFilter *ms_mpeg4_encoder_new();
extern MSFilter *ms_h263p_encoder_new();
MSCodecInfo MPEGinfo={
{
"MPEG1 codec",
0,
MS_FILTER_VIDEO_CODEC,
ms_mpeg_encoder_new,
"This is a MPEG1 codec taken from the ffmpeg project."
},
ms_mpeg_encoder_new,
ms_mpeg_decoder_new,
0,
0,
0, /*bitrate */
0, /*sample freq */
0,
"MPV",
1,
1
};
MSCodecInfo h263pinfo={
{
"H263 codec",
0,
MS_FILTER_VIDEO_CODEC,
ms_h263p_encoder_new,
"This is a H263 codec taken from the ffmpeg project."
},
ms_h263p_encoder_new,
ms_h263p_decoder_new,
0,
0,
0, /*bitrate */
0, /*sample freq */
0,
"H263-1998",
1,
1
};
MSCodecInfo MPEG4info={
{
"MPEG4 codec",
0,
MS_FILTER_VIDEO_CODEC,
ms_mpeg4_encoder_new,
"This is a MPEG4 codec taken from the ffmpeg project."
},
ms_mpeg4_encoder_new,
ms_mpeg4_decoder_new,
0,
0,
0, /*bitrate */
0, /*sample freq */
0,
"MP4V-ES",
1,
1
};
void ms_AVCodec_init()
{
avcodec_init();
avcodec_register_all();
ms_filter_register((MSFilterInfo*)&h263pinfo);
//ms_filter_register((MSFilterInfo*)&MPEG4info);
}
static MSAVDecoderClass *ms_avdecoder_class=NULL;
MSFilter *ms_mpeg_decoder_new()
{
return ms_AVdecoder_new_with_codec(CODEC_ID_MPEG1VIDEO);
}
MSFilter *ms_mpeg4_decoder_new()
{
return ms_AVdecoder_new_with_codec(CODEC_ID_MPEG4);
}
MSFilter *ms_h263p_decoder_new(){
/* H263P decoder doesn't exist in libavcodec...*/
return ms_AVdecoder_new_with_codec(CODEC_ID_H263);
}
MSFilter * ms_AVdecoder_new_with_codec(enum CodecID codec_id)
{
MSAVDecoder *enc;
enc=g_malloc0(sizeof(MSAVDecoder));
if (ms_avdecoder_class==NULL)
{
ms_avdecoder_class=g_malloc0(sizeof(MSAVDecoderClass));
ms_AVdecoder_class_init(ms_avdecoder_class);
}
MS_FILTER(enc)->klass=(MSFilterClass*)ms_avdecoder_class;
ms_AVdecoder_init(enc,avcodec_find_decoder(codec_id));
return MS_FILTER(enc);
}
void ms_AVdecoder_init(MSAVDecoder *dec, AVCodec *codec)
{
gint error;
ms_filter_init(MS_FILTER(dec));
MS_FILTER(dec)->inqueues=dec->q_inputs;
MS_FILTER(dec)->outqueues=dec->q_outputs;
avcodec_get_context_defaults(&dec->av_context);
ms_AVdecoder_set_width(dec,VIDEO_SIZE_CIF_W);
ms_AVdecoder_set_height(dec,VIDEO_SIZE_CIF_H);
dec->av_codec=codec;
dec->av_opened=0;
dec->skip_gob=1;
dec->obufwrap=NULL;
dec->buf_size=0;
}
void ms_AVdecoder_class_init(MSAVDecoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name( MS_FILTER_CLASS(klass),"AVdecoder");
MS_FILTER_CLASS(klass)->max_qinputs=MSAVDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_qoutputs=MSAVDECODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=0;
MS_FILTER_CLASS(klass)->w_maxgran=0;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_AVdecoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_AVdecoder_process;
}
void ms_AVdecoder_uninit(MSAVDecoder *dec)
{
if (dec->obufwrap!=NULL) ms_buffer_destroy(dec->obufwrap);
if (dec->av_opened) avcodec_close(&dec->av_context);
}
void ms_AVdecoder_destroy( MSAVDecoder *obj)
{
ms_AVdecoder_uninit(obj);
g_free(obj);
}
gint ms_AVdecoder_set_format(MSAVDecoder *dec, gchar *fmt)
{
gint format;
if (strcmp(fmt,"YUV420P")==0) format=PIX_FMT_YUV420P;
else if (strcmp(fmt,"YUV422")==0) format=PIX_FMT_YUV422;
else if (strcmp(fmt,"RGB24")==0) format=PIX_FMT_RGB24;
else if (strcmp(fmt,"BGR24")==0) format=PIX_FMT_BGR24;
else if (strcmp(fmt,"YUV422P")==0) format=PIX_FMT_YUV422P;
else if (strcmp(fmt,"YUV444P")==0) format=PIX_FMT_YUV444P;
else {
g_warning("ms_AVdecoder_set_format: unsupported format %s.",fmt);
return -1;
}
dec->output_pix_fmt=format;
return 0;
}
void ms_AVdecoder_process(MSAVDecoder *r)
{
AVFrame orig;
AVFrame transformed;
MSQueue *inq,*outq;
MSMessage *inm,*outm;
gint error;
gint got_picture;
gint len;
unsigned char *data;
AVCodecContext *ctx=&r->av_context;
gint gob_num;
inq=r->q_inputs[0];
outq=r->q_outputs[0];
/* get a picture from the input queue */
inm=ms_queue_get(inq);
g_return_if_fail(inm!=NULL);
if (inm->size >= 2)
{
guint32 *p = (guint32*)inm->data;
char *ph=inm->data;
int PLEN;
gboolean P;
if (!r->av_opened){
error=avcodec_open(&r->av_context, r->av_codec);
if (error!=0) g_warning("avcodec_open() failed: %i",error);
else r->av_opened=1;
}
P=rfc2429_get_P(ph);
PLEN=rfc2429_get_PLEN(ph);
/*printf("receiving new packet; P=%i; V=%i; PLEN=%i; PEBIT=%i\n",P,rfc2429_get_V(ph),PLEN,rfc2429_get_PEBIT(ph));
*/
gob_num = (ntohl(*p) >> 10) & 0x1f;
ms_trace("gob %i, size %i", gob_num, inm->size);
ms_trace("ms_AVdecoder_process: received %08x %08x", ntohl(p[0]), ntohl(p[1]));
/* remove H.263 Payload Header */
if (PLEN>0){
/* we ignore the redundant picture header and
directly go to the bitstream */
inm->data+=PLEN;
inm->size-=PLEN;
}
if (P){
inm->data[0]=inm->data[1]=0;
}else{
/* no PSC omitted */
inm->data+=2;
inm->size-=2;
}
/* accumulate the video packet until we have the rtp markbit*/
memcpy(r->buf_compressed + r->buf_size, inm->data, inm->size);
r->buf_size += inm->size;
if (inm->markbit)
{
unsigned char *data = r->buf_compressed;
ms_trace("ms_AVdecoder_process: decoding %08x %08x %08x", ntohl(((unsigned int *)data)[0]), ntohl(((unsigned int *)data)[1]), ntohl(((unsigned int *)data)[2]));
while (r->buf_size > 0) {
len=avcodec_decode_video(&r->av_context,&orig,&got_picture,data,r->buf_size );
if (len<0) {
ms_warning("ms_AVdecoder_process: error %i.",len);
break;
}
if (got_picture) {
/*g_message("ms_AVdecoder_process: got_picture: width=%i height=%i fmt=%i",
ctx->width,ctx->height,ctx->pix_fmt);*/
/* set the image in the wanted format */
outm=ms_message_alloc();
if (r->obufwrap==NULL){
r->obufwrap=ms_buffer_new(avpicture_get_size(r->output_pix_fmt,r->width,r->height));
r->obufwrap->ref_count++;
}
ms_message_set_buf(outm,r->obufwrap);
avpicture_fill(&transformed,(unsigned char *)outm->data,r->output_pix_fmt,r->width,r->height);
img_convert(&transformed, r->output_pix_fmt,
&orig,ctx->pix_fmt,ctx->width,ctx->height);
ms_queue_put(outq,outm);
}
r->buf_size -= len;
data += len;
}
r->buf_size=0;
}
}
ms_message_destroy(inm);
}
void ms_AVdecoder_set_width(MSAVDecoder *av,gint w)
{
/*av->av_context.width=av->width=w;*/
av->width=w;
}
void ms_AVdecoder_set_height(MSAVDecoder *av,gint h)
{
/*av->av_context.height=av->height=h;*/
av->height=h;
}

View file

@ -1,87 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSAVDECODER_H
#define MSAVDECODER_H
#include "msfilter.h"
#include <avcodec.h>
/*this is the class that implements a AVdecoder filter*/
#define MSAVDECODER_MAX_INPUTS 1 /* max output per filter*/
struct _MSAVDecoder
{
/* the MSAVDecoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSAVDecoder object
in order to the object mechanism to work*/
MSFilter filter;
MSQueue *q_inputs[MSAVDECODER_MAX_INPUTS];
MSQueue *q_outputs[MSAVDECODER_MAX_INPUTS];
AVCodec *av_codec; /*the AVCodec from which this MSFilter is related */
AVCodecContext av_context; /* the context of the AVCodec */
gint av_opened;
int output_pix_fmt;
int width;
int height;
int skip_gob;
unsigned char buf_compressed[100000];
int buf_size;
MSBuffer *obufwrap; /* alternate buffer, when format change is needed*/
};
typedef struct _MSAVDecoder MSAVDecoder;
struct _MSAVDecoderClass
{
/* the MSAVDecoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSAVDecoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
};
typedef struct _MSAVDecoderClass MSAVDecoderClass;
/* PUBLIC */
#define MS_AVDECODER(filter) ((MSAVDecoder*)(filter))
#define MS_AVDECODER_CLASS(klass) ((MSAVDecoderClass*)(klass))
MSFilter *ms_h263p_decoder_new();
MSFilter *ms_mpeg_decoder_new();
MSFilter *ms_mpeg4_decoder_new();
MSFilter * ms_AVdecoder_new_with_codec(enum CodecID codec_id);
gint ms_AVdecoder_set_format(MSAVDecoder *dec, gchar *fmt);
void ms_AVdecoder_set_width(MSAVDecoder *av,gint w);
void ms_AVdecoder_set_height(MSAVDecoder *av,gint h);
/* FOR INTERNAL USE*/
void ms_AVdecoder_init(MSAVDecoder *r, AVCodec *codec);
void ms_AVdecoder_uninit(MSAVDecoder *enc);
void ms_AVdecoder_class_init(MSAVDecoderClass *klass);
void ms_AVdecoder_destroy( MSAVDecoder *obj);
void ms_AVdecoder_process(MSAVDecoder *r);
void ms_AVCodec_init();
#endif

View file

@ -1,258 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msavencoder.h"
#include "msutils.h"
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <netinet/in.h> /* ntohl(3) */
#endif
extern MSCodecInfo MPEG4info;
extern MSCodecInfo MPEGinfo;
extern MSCodecInfo h263pinfo;
static MSAVEncoderClass *ms_avencoder_class=NULL;
static void ms_AVencoder_rtp_callback (AVCodecContext *ctx,void *data, int size, int packet_number);
MSFilter *ms_h263p_encoder_new()
{
/* temporily prefer CODEC_ID_H263 to CODEC_ID_H263P since
ffmpeg does not comply to H233P at profile=0.
*/
return ms_AVencoder_new_with_codec(CODEC_ID_H263P,&h263pinfo);
}
MSFilter *ms_mpeg_encoder_new()
{
return ms_AVencoder_new_with_codec(CODEC_ID_MPEG1VIDEO, &MPEGinfo);
}
MSFilter *ms_mpeg4_encoder_new()
{
return ms_AVencoder_new_with_codec(CODEC_ID_MPEG4,&MPEG4info);
}
MSFilter * ms_AVencoder_new_with_codec(enum CodecID codec_id, MSCodecInfo *info)
{
MSAVEncoder *enc;
AVCodec *avc;
enc=g_malloc0(sizeof(MSAVEncoder));
if (ms_avencoder_class==NULL)
{
ms_avencoder_class=g_malloc0(sizeof(MSAVEncoderClass));
ms_AVencoder_class_init(ms_avencoder_class);
}
MS_FILTER(enc)->klass=(MSFilterClass*)ms_avencoder_class;
avc=avcodec_find_encoder(codec_id);
if (avc==NULL) g_error("unknown av codec.");
ms_AVencoder_init(enc,avc);
return MS_FILTER(enc);
}
void ms_AVencoder_init(MSAVEncoder *enc, AVCodec *codec)
{
AVCodecContext *c=&enc->av_context;
ms_filter_init(MS_FILTER(enc));
MS_FILTER(enc)->inqueues=enc->q_inputs;
MS_FILTER(enc)->outqueues=enc->q_outputs;
/* put default values */
memset(c, 0, sizeof(AVCodecContext));
avcodec_get_context_defaults(c);
/* put sample parameters */
c->bit_rate = 50000;
/* resolution must be a multiple of two */
c->width = VIDEO_SIZE_CIF_W;
c->height = VIDEO_SIZE_CIF_H;
ms_AVencoder_set_frame_rate(enc,15,1);
c->gop_size = 10; /* emit one intra frame every x frames */
c->rtp_mode = 1;
c->rtp_payload_size = 1000;
c->opaque = (void *) enc;
c->rtp_callback = ms_AVencoder_rtp_callback;
c->pix_fmt=PIX_FMT_YUV420P;
enc->av_opened=0;
enc->av_codec=codec;
enc->yuv_buf=NULL;
enc->comp_buf=NULL;
/*set default input format */
ms_AVencoder_set_format(enc,"RGB24");
enc->outm=NULL;
}
void ms_AVencoder_class_init(MSAVEncoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
MS_FILTER_CLASS(klass)->info=0;
MS_FILTER_CLASS(klass)->max_qinputs=MSAVENCODER_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_qoutputs=MSAVENCODER_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=0;
MS_FILTER_CLASS(klass)->w_maxgran=0;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_AVencoder_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_AVencoder_process;
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"AVEncoder");
}
void ms_AVencoder_uninit(MSAVEncoder *enc)
{
if (enc->av_opened)
avcodec_close(&enc->av_context);
if (enc->comp_buf!=NULL) {
ms_buffer_destroy(enc->comp_buf);
enc->comp_buf=NULL;
}
if (enc->yuv_buf!=NULL) {
ms_buffer_destroy(enc->yuv_buf);
enc->yuv_buf=NULL;
}
if (enc->outm!=NULL) ms_message_destroy(enc->outm);
}
void ms_AVencoder_destroy( MSAVEncoder *obj)
{
ms_AVencoder_uninit(obj);
g_free(obj);
}
void ms_AVencoder_set_frame_rate(MSAVEncoder *obj, gint frame_rate, gint frame_rate_base)
{
obj->av_context.time_base.num = frame_rate;
obj->av_context.time_base.den = frame_rate_base;
}
static void ms_AVencoder_rtp_callback (AVCodecContext *ctx, void *data, int size, int packet_number)
{
MSAVEncoder *r = MS_AVENCODER(ctx->opaque);
MSQueue *outq = r->q_outputs[0];
MSMessage *outm;
MSMessage *prev_outm=r->outm;
guint32 *p = (guint32 *) data;
gint gob_num = (ntohl(*p) >> 10) & 0x1f;
/*g_message("ms_AVencoder_rtp_callback: packet %i, size %i, GOB number %i", packet_number, size, gob_num);*/
ms_trace("ms_AVencoder_rtp_callback: received %08x %08x", ntohl(p[0]), ntohl(p[1]));
/* set the H.263 Payload Header (RFC 2429) ie H263-1998 */
p[0] = ntohl( (0x04000000) | (ntohl(p[0]) & 0x0000ffff) ); /* P=1, V=0, PLEN=0 */
ms_trace("ms_AVencoder_rtp_callback: sending %08x %08x", ntohl(p[0]), ntohl(p[1]));
outm = ms_message_new(size);
memcpy(outm->data,data,size);
r->outm=outm;
/*g_message("output video packet of size %i",size);*/
if (prev_outm) {
if (gob_num==0) prev_outm->markbit=TRUE;
ms_queue_put(outq, prev_outm);
}
}
void ms_AVencoder_process(MSAVEncoder *r)
{
AVFrame orig;
AVFrame pict;
AVCodecContext *c=&r->av_context;
MSQueue *inq,*outq;
MSMessage *inm,*outm;
gint error;
inq=r->q_inputs[0];
outq=r->q_outputs[0];
/* get a picture from the input queue */
inm=ms_queue_get(inq);
g_return_if_fail(inm!=NULL);
/* allocate a new image */
if (r->yuv_buf==NULL){
gint bsize = avpicture_get_size(c->pix_fmt,c->width,c->height);
r->yuv_buf=ms_buffer_new(bsize);
r->yuv_buf->ref_count++;
r->comp_buf=ms_buffer_new(bsize/2);
r->comp_buf->ref_count++;
}
if (!r->av_opened || r->av_context.codec == NULL){
error=avcodec_open(c, r->av_codec);
ms_trace("image format is %i.",c->pix_fmt);
if (error!=0) {
g_warning("avcodec_open() failed: %i",error);
return;
}else r->av_opened=1;
}
outm=ms_message_alloc();
/* convert image if necessary */
if (r->input_pix_fmt!=c->pix_fmt){
ms_trace("Changing picture format.");
avpicture_fill((AVPicture*)&orig,inm->data,r->input_pix_fmt,c->width,c->height);
avpicture_fill((AVPicture*)&pict,r->yuv_buf->buffer,c->pix_fmt,c->width,c->height);
if (img_convert((AVPicture*)&pict,c->pix_fmt,(AVPicture*)&orig,r->input_pix_fmt,c->width,c->height) < 0) {
g_warning("img_convert failed");
return;
}
//if (pict.data[0]==NULL) g_error("img_convert failed.");
ms_message_set_buf(outm,r->yuv_buf);
}
else
{
avpicture_fill((AVPicture*)&pict,inm->data,c->pix_fmt,c->width,c->height);
ms_message_set_buf(outm,inm->buffer);
}
/* timestamp used by ffmpeg, unset here */
pict.pts=AV_NOPTS_VALUE;
error=avcodec_encode_video(c, r->comp_buf->buffer, r->comp_buf->size, &pict);
if (error<=0) ms_warning("ms_AVencoder_process: error %i.",error);
else {
ms_trace("ms_AVencoder_process: video encoding done");
/* set the mark bit on the last packet, which contains the end of the frame */
/*
MSMessage *last=ms_queue_peek_last(r->q_outputs[0]);
if (last!=NULL) last->markbit=TRUE;
else g_warning("No last packet ?");
*/
}
if (r->q_outputs[1]!=NULL) ms_queue_put(r->q_outputs[1],outm);
else ms_message_destroy(outm);
ms_message_destroy(inm);
}
gint ms_AVencoder_set_format(MSAVEncoder *enc, gchar *fmt)
{
gint format;
if (strcmp(fmt,"YUV420P")==0) format=PIX_FMT_YUV420P;
else if (strcmp(fmt,"YUV422")==0) format=PIX_FMT_YUV422;
else if (strcmp(fmt,"RGB24")==0) format=PIX_FMT_RGB24;
else if (strcmp(fmt,"BGR24")==0) format=PIX_FMT_BGR24;
else if (strcmp(fmt,"YUV422P")==0) format=PIX_FMT_YUV422P;
else if (strcmp(fmt,"YUV444P")==0) format=PIX_FMT_YUV444P;
else {
g_warning("ms_AVdecoder_set_format: unsupported format %s.",fmt);
return -1;
}
enc->input_pix_fmt=format;
return 0;
}

View file

@ -1,92 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSAVENCODER_H
#define MSAVENCODER_H
#include "msfilter.h"
#include "mscodec.h"
#include <avcodec.h>
/*this is the class that implements a AVencoder filter*/
#define MSAVENCODER_MAX_INPUTS 1 /* max output per filter*/
#define MSAVENCODER_MAX_OUTPUTS 2
struct _MSAVEncoder
{
/* the MSAVEncoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSAVEncoder object
in order to the object mechanism to work*/
MSFilter filter;
MSQueue *q_inputs[MSAVENCODER_MAX_INPUTS];
MSQueue *q_outputs[MSAVENCODER_MAX_OUTPUTS];
AVCodec *av_codec; /*the AVCodec from which this MSFilter is related */
AVCodecContext av_context; /* the context of the AVCodec */
gint input_pix_fmt;
gint av_opened;
MSBuffer *comp_buf;
MSBuffer *yuv_buf;
MSMessage *outm;
};
typedef struct _MSAVEncoder MSAVEncoder;
/* MSAVEncoder always outputs planar YUV and accept any incoming format you should setup using
ms_AVencoder_set_format()
q_outputs[0] is the compressed video stream output
q_outputs[1] is a YUV planar buffer of the image it receives in input.
*/
struct _MSAVEncoderClass
{
/* the MSAVEncoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSAVEncoder class
in order to the class mechanism to work*/
MSFilterClass parent_class;
};
typedef struct _MSAVEncoderClass MSAVEncoderClass;
/* PUBLIC */
#define MS_AVENCODER(filter) ((MSAVEncoder*)(filter))
#define MS_AVENCODER_CLASS(klass) ((MSAVEncoderClass*)(klass))
MSFilter *ms_h263p_encoder_new();
MSFilter *ms_mpeg_encoder_new();
MSFilter *ms_mpeg4_encoder_new();
MSFilter * ms_AVencoder_new_with_codec(enum CodecID codec_id, MSCodecInfo *info);
gint ms_AVencoder_set_format(MSAVEncoder *enc, gchar *fmt);
#define ms_AVencoder_set_width(av,w) (av)->av_context.width=(w)
#define ms_AVencoder_set_height(av,h) (av)->av_context.height=(h)
#define ms_AVencoder_set_bit_rate(av,r) (av)->av_context.bit_rate=(r)
void ms_AVencoder_set_frame_rate(MSAVEncoder *enc, gint frame_rate, gint frame_rate_base);
/* FOR INTERNAL USE*/
void ms_AVencoder_init(MSAVEncoder *r, AVCodec *codec);
void ms_AVencoder_uninit(MSAVEncoder *enc);
void ms_AVencoder_class_init(MSAVEncoderClass *klass);
void ms_AVencoder_destroy( MSAVEncoder *obj);
void ms_AVencoder_process(MSAVEncoder *r);
#endif

View file

@ -1,91 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msbuffer.h"
#include "msutils.h"
#include <string.h>
MSBuffer * ms_buffer_new(guint32 size)
{
MSBuffer *buf;
buf=(MSBuffer*)g_malloc(sizeof(MSBuffer)+size);
buf->ref_count=0;
buf->size=size;
ms_trace("ms_buffer_new: Allocating buffer of %i bytes.",size);
/* allocate the data buffer: there is a lot of optmisation that can be done by using a pool of cached buffers*/
buf->buffer=((char*)(buf))+sizeof(MSBuffer); /* to avoid to do two allocations,
buffer info and buffer are contigous.*/
buf->freefn=NULL;
buf->freearg=NULL;
return(buf);
}
MSBuffer *ms_buffer_new_with_buf(char *extbuf, int size,void (*freefn)(void *), void *freearg)
{
MSBuffer *buf;
buf=(MSBuffer*)g_malloc(sizeof(MSBuffer));
buf->ref_count=0;
buf->size=size;
buf->buffer=extbuf;
buf->freefn=freefn;
buf->freearg=freearg;
return(buf);
}
void ms_buffer_destroy(MSBuffer *buf)
{
if (buf->freefn!=NULL) buf->freefn(buf->freearg);
g_free(buf);
}
MSMessage *ms_message_alloc()
{
MSMessage *m=g_malloc(sizeof(MSMessage));
memset(m,0,sizeof(MSMessage));
return m;
}
MSMessage *ms_message_new(gint size)
{
MSMessage *m=ms_message_alloc();
MSBuffer *buf=ms_buffer_new(size);
ms_message_set_buf(m,buf);
return m;
}
void ms_message_destroy(MSMessage *m)
{
/* the buffer is freed if its ref_count goes to zero */
if (m->buffer!=NULL){
m->buffer->ref_count--;
if (m->buffer->ref_count==0) ms_buffer_destroy(m->buffer);
}
g_free(m);
}
MSMessage * ms_message_dup(MSMessage *m)
{
MSMessage *msg=ms_message_alloc();
ms_message_set_buf(msg,m->buffer);
return msg;
}

View file

@ -1,78 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSBUFFER_H
#define MSBUFFER_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_GLIB
#include <glib.h>
#else
#include <uglib.h>
#endif
#define MS_BUFFER_LARGE 4092
typedef struct _MSBuffer
{
gchar *buffer;
guint32 size;
gint ref_count;
void (*freefn)(void *);
void *freearg;
}MSBuffer;
MSBuffer * ms_buffer_new(guint32 size);
MSBuffer *ms_buffer_new_with_buf(char *extbuf, int size,void (*freefn)(void *), void *freearg);
void ms_buffer_destroy(MSBuffer *buf);
struct _MSMessage
{
MSBuffer *buffer; /* points to a MSBuffer */
char *data; /*points to buffer->buffer */
guint32 size; /* the size of the buffer to read in data. It may not be the
physical size (I mean buffer->buffer->size */
struct _MSMessage *next;
struct _MSMessage *prev; /* MSMessage are queued into MSQueues */
gboolean markbit;
};
typedef struct _MSMessage MSMessage;
MSMessage *ms_message_new(gint size);
#define ms_message_set_buf(m,b) do { (b)->ref_count++; (m)->buffer=(b); (m)->data=(b)->buffer; (m)->size=(b)->size; }while(0)
#define ms_message_unset_buf(m) do { (m)->buffer->ref_count--; (m)->buffer=NULL; (m)->size=0; (m)->data=NULL; } while(0)
#define ms_message_size(m) (m)->size
void ms_message_destroy(MSMessage *m);
MSMessage * ms_message_dup(MSMessage *m);
/* allocate a single message without buffer */
MSMessage *ms_message_alloc();
#endif

View file

@ -1,259 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mscodec.h"
#ifndef _WIN32
# include "msGSMdecoder.h"
# include "msLPC10decoder.h"
#endif
#include "msMUlawdec.h"
#include "msAlawdec.h"
#ifdef TRUESPEECH
extern MSCodecInfo TrueSpeechinfo;
#endif
#ifdef VIDEO_ENABLED
extern void ms_AVCodec_init();
#endif
#define UDP_HDR_SZ 8
#define RTP_HDR_SZ 12
#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/
/* register all statically linked codecs */
void ms_codec_register_all()
{
#ifndef _WIN32
ms_filter_register(MS_FILTER_INFO(&GSMinfo));
ms_filter_register(MS_FILTER_INFO(&LPC10info));
#endif
ms_filter_register(MS_FILTER_INFO(&MULAWinfo));
ms_filter_register(MS_FILTER_INFO(&ALAWinfo));
#ifdef TRUESPEECH
ms_filter_register(MS_FILTER_INFO(&TrueSpeechinfo));
#endif
#ifdef VIDEO_ENABLED
ms_AVCodec_init();
#endif
}
/* returns a list of MSCodecInfo */
GList * ms_codec_get_all_audio()
{
GList *audio_codecs=NULL;
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if (info->type==MS_FILTER_AUDIO_CODEC){
audio_codecs=g_list_append(audio_codecs,info);
}
elem=g_list_next(elem);
}
return audio_codecs;
}
MSCodecInfo * ms_audio_codec_info_get(gchar *name)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ( (info->type==MS_FILTER_AUDIO_CODEC) ){
MSCodecInfo *codinfo=(MSCodecInfo *)info;
if (strcmp(codinfo->description,name)==0){
return MS_CODEC_INFO(info);
}
}
elem=g_list_next(elem);
}
return NULL;
}
MSCodecInfo * ms_video_codec_info_get(gchar *name)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ( (info->type==MS_FILTER_VIDEO_CODEC) ){
MSCodecInfo *codinfo=(MSCodecInfo *)info;
if (strcmp(codinfo->description,name)==0){
return MS_CODEC_INFO(info);
}
}
elem=g_list_next(elem);
}
return NULL;
}
/* returns a list of MSCodecInfo */
GList * ms_codec_get_all_video()
{
GList *video_codecs=NULL;
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if (info->type==MS_FILTER_VIDEO_CODEC){
video_codecs=g_list_append(video_codecs,info);
}
elem=g_list_next(elem);
}
return video_codecs;
}
MSFilter * ms_encoder_new(gchar *name)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){
MSCodecInfo *codinfo=(MSCodecInfo *)elem->data;
if (strcmp(info->name,name)==0){
return codinfo->encoder();
}
}
elem=g_list_next(elem);
}
return NULL;
}
MSFilter * ms_decoder_new(gchar *name)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){
MSCodecInfo *codinfo=(MSCodecInfo *)elem->data;
if (strcmp(info->name,name)==0){
return codinfo->decoder();
}
}
elem=g_list_next(elem);
}
return NULL;
}
MSFilter * ms_encoder_new_with_pt(gint pt)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){
MSCodecInfo *codinfo=(MSCodecInfo *)elem->data;
if (codinfo->pt==pt){
return codinfo->encoder();
}
}
elem=g_list_next(elem);
}
return NULL;
}
MSFilter * ms_decoder_new_with_pt(gint pt)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){
MSCodecInfo *codinfo=(MSCodecInfo *)elem->data;
if (codinfo->pt==pt){
return codinfo->decoder();
}
}
elem=g_list_next(elem);
}
return NULL;
}
MSFilter * ms_decoder_new_with_string_id(gchar *id)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){
MSCodecInfo *codinfo=(MSCodecInfo *)elem->data;
if (strcasecmp(codinfo->description,id)==0){
return codinfo->decoder();
}
}
elem=g_list_next(elem);
}
return NULL;
}
MSFilter * ms_encoder_new_with_string_id(gchar *id)
{
GList *elem=filter_list;
MSFilterInfo *info;
while (elem!=NULL)
{
info=(MSFilterInfo *)elem->data;
if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){
MSCodecInfo *codinfo=(MSCodecInfo *)elem->data;
if (strcasecmp(codinfo->description,id)==0){
return codinfo->encoder();
}
}
elem=g_list_next(elem);
}
return NULL;
}
/* return 0 if codec can be used with bandwidth, -1 else*/
int ms_codec_is_usable(MSCodecInfo *codec,double bandwidth)
{
double codec_band;
double npacket;
double packet_size;
if (((MSFilterInfo*)codec)->type==MS_FILTER_AUDIO_CODEC)
{
/* calculate the total bandwdith needed by codec (including headers for rtp, udp, ip)*/
/* number of packet per second*/
npacket=2.0*(double)(codec->rate)/(double)(codec->fr_size);
packet_size=(double)(codec->dt_size)+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ;
codec_band=packet_size*8.0*npacket;
}
else return -1;
return(codec_band<bandwidth);
}

View file

@ -1,67 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSCODEC_H
#define MSCODEC_H
#include "msfilter.h"
struct _MSCodecInfo
{
MSFilterInfo info;
MSFilterNewFunc encoder;
MSFilterNewFunc decoder;
gint fr_size; /* size in char of the uncompressed frame */
gint dt_size; /* size in char of the compressed frame */
gint bitrate; /* the minimum bit rate in bits/second */
gint rate; /*frequency */
gint pt; /* the payload type number associated with this codec*/
gchar *description; /* a rtpmap field to describe the codec */
guint is_usable:1; /* linphone set this flag to remember if it can use this codec considering the total bandwidth*/
guint is_selected:1; /* linphone (user) set this flag if he allows this codec to be used*/
};
typedef struct _MSCodecInfo MSCodecInfo;
MSFilter * ms_encoder_new(gchar *name);
MSFilter * ms_decoder_new(gchar *name);
MSFilter * ms_encoder_new_with_pt(gint pt);
MSFilter * ms_decoder_new_with_pt(gint pt);
MSFilter * ms_encoder_new_with_string_id(gchar *id);
MSFilter * ms_decoder_new_with_string_id(gchar *id);
/* return 0 if codec can be used with bandwidth, -1 else*/
int ms_codec_is_usable(MSCodecInfo *codec,double bandwidth);
GList * ms_codec_get_all_audio();
GList * ms_codec_get_all_video();
MSCodecInfo * ms_audio_codec_info_get(gchar *name);
MSCodecInfo * ms_video_codec_info_get(gchar *name);
/* register all statically linked codecs */
void ms_codec_register_all();
#define MS_CODEC_INFO(codinfo) ((MSCodecInfo*)codinfo)
#endif

View file

@ -1,96 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mscopy.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
static MSCopyClass *ms_copy_class=NULL;
MSFilter * ms_copy_new(void)
{
MSCopy *r;
r=g_new(MSCopy,1);
ms_copy_init(r);
if (ms_copy_class==NULL)
{
ms_copy_class=g_new(MSCopyClass,1);
ms_copy_class_init(ms_copy_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_copy_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_copy_init(MSCopy *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->r_mingran=MSCOPY_DEF_GRAN;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSCOPY_MAX_INPUTS);
memset(r->f_outputs,0,sizeof(MSFifo*)*MSCOPY_MAX_INPUTS);
}
void ms_copy_class_init(MSCopyClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"fifocopier");
MS_FILTER_CLASS(klass)->max_finputs=MSCOPY_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSCOPY_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=MSCOPY_DEF_GRAN;
MS_FILTER_CLASS(klass)->w_maxgran=MSCOPY_DEF_GRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_copy_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_copy_process;
}
void ms_copy_process(MSCopy *r)
{
MSFifo *fi,*fo;
int err1;
gint gran=MS_FILTER(r)->klass->r_maxgran;
void *s,*d;
/* process output fifos, but there is only one for this class of filter*/
fi=r->f_inputs[0];
fo=r->f_outputs[0];
if (fi!=NULL)
{
err1=ms_fifo_get_read_ptr(fi,gran,&s);
if (err1>0) err1=ms_fifo_get_write_ptr(fo,gran,&d);
if (err1>0)
{
memcpy(d,s,gran);
}
}
}
void ms_copy_destroy( MSCopy *obj)
{
g_free(obj);
}

View file

@ -1,61 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSCOPY_H
#define MSCOPY_H
#include "msfilter.h"
/*this is the class that implements a copy filter*/
#define MSCOPY_MAX_INPUTS 1 /* max output per filter*/
#define MSCOPY_DEF_GRAN 64 /* the default granularity*/
typedef struct _MSCopy
{
/* the MSCopy derivates from MSFilter, so the MSFilter object MUST be the first of the MSCopy object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSCOPY_MAX_INPUTS];
MSFifo *f_outputs[MSCOPY_MAX_INPUTS];
} MSCopy;
typedef struct _MSCopyClass
{
/* the MSCopy derivates from MSFilter, so the MSFilter class MUST be the first of the MSCopy class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSCopyClass;
/* PUBLIC */
#define MS_COPY(filter) ((MSCopy*)(filter))
#define MS_COPY_CLASS(klass) ((MSCopyClass*)(klass))
MSFilter * ms_copy_new(void);
/* FOR INTERNAL USE*/
void ms_copy_init(MSCopy *r);
void ms_copy_class_init(MSCopyClass *klass);
void ms_copy_destroy( MSCopy *obj);
void ms_copy_process(MSCopy *r);
#endif

View file

@ -1,94 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a dispatcher of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msfdispatcher.h"
static MSFdispatcherClass *ms_fdispatcher_class=NULL;
MSFilter * ms_fdispatcher_new(void)
{
MSFdispatcher *obj;
obj=g_malloc(sizeof(MSFdispatcher));
if (ms_fdispatcher_class==NULL){
ms_fdispatcher_class=g_malloc(sizeof(MSFdispatcherClass));
ms_fdispatcher_class_init(ms_fdispatcher_class);
}
MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_fdispatcher_class);
ms_fdispatcher_init(obj);
return MS_FILTER(obj);
}
void ms_fdispatcher_init(MSFdispatcher *obj)
{
ms_filter_init(MS_FILTER(obj));
MS_FILTER(obj)->infifos=obj->f_inputs;
MS_FILTER(obj)->outfifos=obj->f_outputs;
MS_FILTER(obj)->r_mingran=MS_FDISPATCHER_DEF_GRAN;
memset(obj->f_inputs,0,sizeof(MSFifo*)*MS_FDISPATCHER_MAX_INPUTS);
memset(obj->f_outputs,0,sizeof(MSFifo*)*MS_FDISPATCHER_MAX_OUTPUTS);
}
void ms_fdispatcher_class_init(MSFdispatcherClass *klass)
{
MSFilterClass *parent_class=MS_FILTER_CLASS(klass);
ms_filter_class_init(parent_class);
ms_filter_class_set_name(parent_class,"fdispatcher");
parent_class->max_finputs=MS_FDISPATCHER_MAX_INPUTS;
parent_class->max_foutputs=MS_FDISPATCHER_MAX_OUTPUTS;
parent_class->r_maxgran=MS_FDISPATCHER_DEF_GRAN;
parent_class->w_maxgran=MS_FDISPATCHER_DEF_GRAN;
parent_class->destroy=(MSFilterDestroyFunc)ms_fdispatcher_destroy;
parent_class->process=(MSFilterProcessFunc)ms_fdispatcher_process;
}
void ms_fdispatcher_destroy( MSFdispatcher *obj)
{
g_free(obj);
}
void ms_fdispatcher_process(MSFdispatcher *obj)
{
gint i;
MSFifo *inf=obj->f_inputs[0];
if (inf!=NULL){
void *s,*d;
/* dispatch fifos */
while ( ms_fifo_get_read_ptr(inf,MS_FDISPATCHER_DEF_GRAN,&s) >0 ){
for (i=0;i<MS_FDISPATCHER_MAX_OUTPUTS;i++){
MSFifo *outf=obj->f_outputs[i];
if (outf!=NULL)
{
ms_fifo_get_write_ptr(outf,MS_FDISPATCHER_DEF_GRAN,&d);
if (d!=NULL) memcpy(d,s,MS_FDISPATCHER_DEF_GRAN);
}
}
}
}
}

View file

@ -1,61 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a dispatcher of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSFDISPATCHER_H
#define MSFDISPATCHER_H
#include "msfilter.h"
/*this is the class that implements a fdispatcher filter*/
#define MS_FDISPATCHER_MAX_INPUTS 1
#define MS_FDISPATCHER_MAX_OUTPUTS 5
#define MS_FDISPATCHER_DEF_GRAN 64 /* the default granularity*/
typedef struct _MSFdispatcher
{
/* the MSFdispatcher derivates from MSFilter, so the MSFilter object MUST be the first of the MSFdispatcher object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MS_FDISPATCHER_MAX_INPUTS];
MSFifo *f_outputs[MS_FDISPATCHER_MAX_OUTPUTS];
} MSFdispatcher;
typedef struct _MSFdispatcherClass
{
/* the MSFdispatcher derivates from MSFilter, so the MSFilter class MUST be the first of the MSFdispatcher class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSFdispatcherClass;
/* PUBLIC */
#define MS_FDISPATCHER(filter) ((MSFdispatcher*)(filter))
#define MS_FDISPATCHER_CLASS(klass) ((MSFdispatcherClass*)(klass))
MSFilter * ms_fdispatcher_new(void);
/* FOR INTERNAL USE*/
void ms_fdispatcher_init(MSFdispatcher *r);
void ms_fdispatcher_class_init(MSFdispatcherClass *klass);
void ms_fdispatcher_destroy( MSFdispatcher *obj);
void ms_fdispatcher_process(MSFdispatcher *r);
#endif

View file

@ -1,167 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <errno.h>
#include <string.h>
#include "msutils.h"
#include "msfifo.h"
MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset)
{
MSFifo *fifo;
gint saved_offset=MAX(r_gran+r_offset,w_offset);
g_return_val_if_fail(saved_offset<=(buf->size),NULL);
fifo=g_malloc(sizeof(MSFifo));
fifo->buffer=buf;
fifo->r_gran=r_gran;
fifo->w_gran=w_gran;
fifo->begin=fifo->wr_ptr=fifo->rd_ptr=buf->buffer+saved_offset;
fifo->readsize=0;
fifo->size=fifo->writesize=buf->size-saved_offset;
fifo->saved_offset= saved_offset;
fifo->r_end=fifo->w_end=buf->buffer+buf->size;
fifo->pre_end=fifo->w_end-saved_offset;
buf->ref_count++;
fifo->prev_data=NULL;
fifo->next_data=NULL;
ms_trace("fifo base=%x, begin=%x, end=%x, saved_offset=%i, size=%i"
,fifo->buffer->buffer,fifo->begin,fifo->w_end,fifo->saved_offset,fifo->size);
return(fifo);
}
MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset,
gint min_fifo_size)
{
MSFifo *fifo;
MSBuffer *buf;
gint saved_offset=MAX(r_gran+r_offset,w_offset);
gint fifo_size;
if (min_fifo_size==0) min_fifo_size=w_gran;
/* we must allocate a fifo with a size multiple of min_fifo_size,
with a saved_offset */
if (min_fifo_size>MS_BUFFER_LARGE)
fifo_size=(min_fifo_size) + saved_offset;
else fifo_size=(6*min_fifo_size) + saved_offset;
buf=ms_buffer_new(fifo_size);
fifo=ms_fifo_new(buf,r_gran,w_gran,r_offset,w_offset);
ms_trace("fifo_size=%i",fifo_size);
return(fifo);
}
void ms_fifo_destroy( MSFifo *fifo)
{
g_free(fifo);
}
void ms_fifo_destroy_with_buffer(MSFifo *fifo)
{
ms_buffer_destroy(fifo->buffer);
ms_fifo_destroy(fifo);
}
gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
{
gchar *rnext;
*ret_ptr=NULL;
//ms_trace("ms_fifo_get_read_ptr: entering.");
g_return_val_if_fail(bsize<=fifo->r_gran,-EINVAL);
if (bsize>fifo->readsize)
{
ms_trace("Not enough data: bsize=%i, readsize=%i",bsize,fifo->readsize);
return -1;
}
rnext=fifo->rd_ptr+bsize;
if (rnext<=fifo->r_end){
*ret_ptr=fifo->rd_ptr;
fifo->rd_ptr=rnext;
}else{
int unread=fifo->r_end-fifo->rd_ptr;
*ret_ptr=fifo->begin-unread;
memcpy(fifo->buffer->buffer,fifo->r_end-fifo->saved_offset,fifo->saved_offset);
fifo->rd_ptr=(char*)(*ret_ptr) + bsize;
fifo->r_end=fifo->w_end; /* this is important ! */
ms_trace("moving read ptr to %x",fifo->rd_ptr);
}
/* update write size*/
fifo->writesize+=bsize;
fifo->readsize-=bsize;
return bsize;
}
void ms_fifo_update_write_ptr(MSFifo *fifo, gint written){
gint reserved=fifo->wr_ptr-fifo->prev_wr_ptr;
gint unwritten;
g_return_if_fail(reserved>=0);
unwritten=reserved-written;
g_return_if_fail(unwritten>=0);
/* fix readsize and writesize */
fifo->readsize-=unwritten;
fifo->writesize+=unwritten;
fifo->wr_ptr=fifo->prev_wr_ptr+written;
}
gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
{
gchar *wnext;
*ret_ptr=NULL;
//ms_trace("ms_fifo_get_write_ptr: Entering.");
g_return_val_if_fail(bsize<=fifo->w_gran,-EINVAL);
if (bsize>fifo->writesize)
{
ms_trace("Not enough space: bsize=%i, writesize=%i",bsize,fifo->writesize);
*ret_ptr=NULL;
return -1;
}
wnext=fifo->wr_ptr+bsize;
if (wnext<=fifo->w_end){
*ret_ptr=fifo->wr_ptr;
fifo->wr_ptr=wnext;
}else{
*ret_ptr=fifo->begin;
fifo->r_end=fifo->wr_ptr;
fifo->wr_ptr=fifo->begin+bsize;
ms_trace("moving write ptr to %x",fifo->wr_ptr);
}
fifo->prev_wr_ptr=*ret_ptr;
/* update readsize*/
fifo->readsize+=bsize;
fifo->writesize-=bsize;
//ms_trace("ms_fifo_get_write_ptr: readsize=%i, writesize=%i",fifo->readsize,fifo->writesize);
return bsize;
}
gint ms_fifo_get_rw_ptr(MSFifo *f1,void **p1,gint minsize1,
MSFifo *f2,void **p2,gint minsize2)
{
gint rbsize,wbsize;
rbsize=MIN(f1->readsize,(f1->pre_end-f1->rd_ptr));
wbsize=MIN(f2->writesize,(f2->w_end-f2->wr_ptr));
return 0;
}

View file

@ -1,73 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_GLIB
#include <glib.h>
#else
#include "glist.h"
#endif
#include "msbuffer.h"
typedef struct _MSFifo
{
gint r_gran; /*maximum granularity for reading*/
gint w_gran; /*maximum granularity for writing*/
gchar * rd_ptr; /* read pointer on the position where there is something to read on the MSBuffer */
guint32 readsize;
gchar * wr_ptr;
gchar * prev_wr_ptr;
guint32 writesize; /* write pointer on the position where it is possible to write on the MSBuffer */
gchar * begin; /* rd_ptr et wr_ptr must all be >=begin*/
guint32 size; /* the length of the fifo, but this may not be equal to buffer->size*/
guint32 saved_offset;
gchar * pre_end; /* the end of the buffer that is copied at the begginning when we wrap around*/
gchar * w_end; /* when a wr ptr is expected to exceed end_offset,
it must be wrapped around to go at the beginning of the buffer. This is the end of the buffer*/
gchar * r_end; /* this is the last position written at the end of the fifo. If a read ptr is expected to
exceed this pointer, it must be put at the begginning of the buffer */
void *prev_data; /*user data, usually the writing MSFilter*/
void *next_data; /* user data, usually the reading MSFilter */
MSBuffer *buffer;
} MSFifo;
/* constructor*/
/* r_gran: max granularity for reading (in number of bytes)*/
/* w_gran: max granularity for writing (in number of bytes)*/
/* r_offset: number of bytes that are kept available behind read pointer (for recursive filters)*/
/* w_offset: number of bytes that are kept available behind write pointer (for recursive filters)*/
/* buf is a MSBuffer that should be compatible with the above parameter*/
MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset);
/*does the same that ms_fifo_new(), but also allocate a compatible buffer automatically*/
MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset, gint min_buffer_size);
void ms_fifo_destroy( MSFifo *fifo);
void ms_fifo_destroy_with_buffer(MSFifo *fifo);
/* get data to read */
gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr);
/* get a buffer to write*/
gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr);
/* in case the buffer got by ms_fifo_get_write_ptr() could not be filled completely, you must
tell it by using this function */
void ms_fifo_update_write_ptr(MSFifo *fifo, gint written);

View file

@ -1,537 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <errno.h>
#include "msfilter.h"
void ms_filter_init(MSFilter *filter)
{
filter->finputs=0;
filter->foutputs=0;
filter->qinputs=0;
filter->qoutputs=0;
filter->infifos=NULL;
filter->outfifos=NULL;
filter->inqueues=NULL;
filter->outqueues=NULL;
filter->lock=g_mutex_new();
filter->min_fifo_size=0x7fff;
filter->notify_event=NULL;
filter->userdata=NULL;
}
void ms_filter_uninit(MSFilter *filter)
{
g_mutex_free(filter->lock);
}
void ms_filter_class_init(MSFilterClass *filterclass)
{
filterclass->name=NULL;
filterclass->max_finputs=0;
filterclass->max_foutputs=0;
filterclass->max_qinputs=0;
filterclass->max_qoutputs=0;
filterclass->r_maxgran=0;
filterclass->w_maxgran=0;
filterclass->r_offset=0;
filterclass->w_offset=0;
filterclass->set_property=NULL;
filterclass->get_property=NULL;
filterclass->setup=NULL;
filterclass->unsetup=NULL;
filterclass->process=NULL;
filterclass->destroy=NULL;
filterclass->attributes=0;
filterclass->ref_count=0;
}
/* find output queue */
gint find_oq(MSFilter *m1,MSQueue *oq)
{
gint i;
for (i=0;i<MS_FILTER_GET_CLASS(m1)->max_qoutputs;i++){
if (m1->outqueues[i]==oq) return i;
}
return -1;
}
/* find input queue */
gint find_iq(MSFilter *m1,MSQueue *iq)
{
gint i;
for (i=0;i<MS_FILTER_GET_CLASS(m1)->max_qinputs;i++){
if (m1->inqueues[i]==iq) return i;
}
return -1;
}
/* find output fifo */
gint find_of(MSFilter *m1,MSFifo *of)
{
gint i;
for (i=0;i<MS_FILTER_GET_CLASS(m1)->max_foutputs;i++){
if (m1->outfifos[i]==of) return i;
}
return -1;
}
/* find input fifo */
gint find_if(MSFilter *m1,MSFifo *inf)
{
gint i;
for (i=0;i<MS_FILTER_GET_CLASS(m1)->max_finputs;i++){
if (m1->infifos[i]==inf) return i;
}
return -1;
}
#define find_free_iq(_m1) find_iq(_m1,NULL)
#define find_free_oq(_m1) find_oq(_m1,NULL)
#define find_free_if(_m1) find_if(_m1,NULL)
#define find_free_of(_m1) find_of(_m1,NULL)
int ms_filter_add_link(MSFilter *m1, MSFilter *m2)
{
gint m1_q=-1;
gint m1_f=-1;
gint m2_q=-1;
gint m2_f=-1;
/* determine the type of link we can add */
m1_q=find_free_oq(m1);
m1_f=find_free_of(m1);
m2_q=find_free_iq(m2);
m2_f=find_free_if(m2);
if ((m1_q!=-1) && (m2_q!=-1)){
/* link with queues */
ms_trace("m1_q=%i , m2_q=%i",m1_q,m2_q);
return ms_filter_link(m1,m1_q,m2,m2_q,LINK_QUEUE);
}
if ((m1_f!=-1) && (m2_f!=-1)){
/* link with queues */
ms_trace("m1_f=%i , m2_f=%i",m1_f,m2_f);
return ms_filter_link(m1,m1_f,m2,m2_f,LINK_FIFO);
}
g_warning("ms_filter_add_link: could not link.");
return -1;
}
/**
* ms_filter_link:
* @m1: A #MSFilter object.
* @pin1: The pin number on @m1.
* @m2: A #MSFilter object.
* @pin2: The pin number on @m2.
* @linktype: Type of connection, it may be #LINK_QUEUE, #LINK_FIFOS.
*
* This function links two MSFilter object between them. It must be used to make chains of filters.
* All data outgoing from pin1 of m1 will go to the input pin2 of m2.
* The way to communicate can be fifos or queues, depending of the nature of the filters. Filters can have
* multiple queue pins and multiple fifo pins, but most of them have only one queue input/output or only one
* fifo input/output. Fifos are usally used by filters doing audio processing, while queues are used by filters doing
* video processing.
*
* Returns: 0 if successfull, a negative value reprensenting the errno.h error.
*/
int ms_filter_link(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2, int linktype)
{
MSQueue *q;
MSFifo *fifo;
g_message("ms_filter_add_link: %s,%i -> %s,%i",m1->klass->name,pin1,m2->klass->name,pin2);
switch(linktype)
{
case LINK_QUEUE:
/* Are filter m1 and m2 able to accept more queues connections ?*/
g_return_val_if_fail(m1->qoutputs<MS_FILTER_GET_CLASS(m1)->max_qoutputs,-EMLINK);
g_return_val_if_fail(m2->qinputs<MS_FILTER_GET_CLASS(m2)->max_qinputs,-EMLINK);
/* Are filter m1 and m2 valid with their inputs and outputs ?*/
g_return_val_if_fail(m1->outqueues!=NULL,-EFAULT);
g_return_val_if_fail(m2->inqueues!=NULL,-EFAULT);
/* are the requested pins exists ?*/
g_return_val_if_fail(pin1<MS_FILTER_GET_CLASS(m1)->max_qoutputs,-EINVAL);
g_return_val_if_fail(pin2<MS_FILTER_GET_CLASS(m2)->max_qinputs,-EINVAL);
/* are the requested pins free ?*/
g_return_val_if_fail(m1->outqueues[pin1]==NULL,-EBUSY);
g_return_val_if_fail(m2->inqueues[pin2]==NULL,-EBUSY);
q=ms_queue_new();
m1->outqueues[pin1]=m2->inqueues[pin2]=q;
m1->qoutputs++;
m2->qinputs++;
q->prev_data=(void*)m1;
q->next_data=(void*)m2;
break;
case LINK_FIFO:
/* Are filter m1 and m2 able to accept more fifo connections ?*/
g_return_val_if_fail(m1->foutputs<MS_FILTER_GET_CLASS(m1)->max_foutputs,-EMLINK);
g_return_val_if_fail(m2->finputs<MS_FILTER_GET_CLASS(m2)->max_finputs,-EMLINK);
/* Are filter m1 and m2 valid with their inputs and outputs ?*/
g_return_val_if_fail(m1->outfifos!=NULL,-EFAULT);
g_return_val_if_fail(m2->infifos!=NULL,-EFAULT);
/* are the requested pins exists ?*/
g_return_val_if_fail(pin1<MS_FILTER_GET_CLASS(m1)->max_foutputs,-EINVAL);
g_return_val_if_fail(pin2<MS_FILTER_GET_CLASS(m2)->max_finputs,-EINVAL);
/* are the requested pins free ?*/
g_return_val_if_fail(m1->outfifos[pin1]==NULL,-EBUSY);
g_return_val_if_fail(m2->infifos[pin2]==NULL,-EBUSY);
if (MS_FILTER_GET_CLASS(m1)->attributes & FILTER_IS_SOURCE)
{
/* configure min_fifo_size */
fifo=ms_fifo_new_with_buffer(MS_FILTER_GET_CLASS(m2)->r_maxgran,
MS_FILTER_GET_CLASS(m1)->w_maxgran,
MS_FILTER_GET_CLASS(m2)->r_offset,
MS_FILTER_GET_CLASS(m1)->w_offset,
MS_FILTER_GET_CLASS(m1)->w_maxgran);
m2->min_fifo_size=MS_FILTER_GET_CLASS(m1)->w_maxgran;
}
else
{
gint next_size;
ms_trace("ms_filter_add_link: min_fifo_size=%i",m1->min_fifo_size);
fifo=ms_fifo_new_with_buffer(MS_FILTER_GET_CLASS(m2)->r_maxgran,
MS_FILTER_GET_CLASS(m1)->w_maxgran,
MS_FILTER_GET_CLASS(m2)->r_offset,
MS_FILTER_GET_CLASS(m1)->w_offset,
m1->min_fifo_size);
if (MS_FILTER_GET_CLASS(m2)->r_maxgran>0){
next_size=(m1->min_fifo_size*
(MS_FILTER_GET_CLASS(m2)->w_maxgran)) /
(MS_FILTER_GET_CLASS(m2)->r_maxgran);
}else next_size=m1->min_fifo_size;
ms_trace("ms_filter_add_link: next_size=%i",next_size);
m2->min_fifo_size=next_size;
}
m1->outfifos[pin1]=m2->infifos[pin2]=fifo;
m1->foutputs++;
m2->finputs++;
fifo->prev_data=(void*)m1;
fifo->next_data=(void*)m2;
break;
}
return 0;
}
/**
* ms_filter_unlink:
* @m1: A #MSFilter object.
* @pin1: The pin number on @m1.
* @m2: A #MSFilter object.
* @pin2: The pin number on @m2.
* @linktype: Type of connection, it may be #LINK_QUEUE, #LINK_FIFOS.
*
* Unlink @pin1 of filter @m1 from @pin2 of filter @m2. @linktype specifies what type of connection is removed.
*
* Returns: 0 if successfull, a negative value reprensenting the errno.h error.
*/
int ms_filter_unlink(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2,gint linktype)
{
switch(linktype)
{
case LINK_QUEUE:
/* Are filter m1 and m2 valid with their inputs and outputs ?*/
g_return_val_if_fail(m1->outqueues!=NULL,-EFAULT);
g_return_val_if_fail(m2->inqueues!=NULL,-EFAULT);
/* are the requested pins exists ?*/
g_return_val_if_fail(pin1<MS_FILTER_GET_CLASS(m1)->max_qoutputs,-EINVAL);
g_return_val_if_fail(pin2<MS_FILTER_GET_CLASS(m2)->max_qinputs,-EINVAL);
/* are the requested pins busy ?*/
g_return_val_if_fail(m1->outqueues[pin1]!=NULL,-ENOENT);
g_return_val_if_fail(m2->inqueues[pin2]!=NULL,-ENOENT);
/* are the two pins connected together ?*/
g_return_val_if_fail(m1->outqueues[pin1]==m2->inqueues[pin2],-EINVAL);
ms_queue_destroy(m1->outqueues[pin1]);
m1->outqueues[pin1]=m2->inqueues[pin2]=NULL;
m1->qoutputs--;
m2->qinputs--;
break;
case LINK_FIFO:
/* Are filter m1 and m2 valid with their inputs and outputs ?*/
g_return_val_if_fail(m1->outfifos!=NULL,-EFAULT);
g_return_val_if_fail(m2->infifos!=NULL,-EFAULT);
/* are the requested pins exists ?*/
g_return_val_if_fail(pin1<MS_FILTER_GET_CLASS(m1)->max_foutputs,-EINVAL);
g_return_val_if_fail(pin2<MS_FILTER_GET_CLASS(m2)->max_finputs,-EINVAL);
/* are the requested pins busy ?*/
g_return_val_if_fail(m1->outfifos[pin1]!=NULL,-ENOENT);
g_return_val_if_fail(m2->infifos[pin2]!=NULL,-ENOENT);
/* are the two pins connected together ?*/
g_return_val_if_fail(m1->outfifos[pin1]==m2->infifos[pin2],-EINVAL);
ms_fifo_destroy_with_buffer(m1->outfifos[pin1]);
m1->outfifos[pin1]=m2->infifos[pin2]=NULL;
m1->foutputs--;
m2->finputs--;
break;
}
return 0;
}
/**
*ms_filter_remove_links:
*@m1: a filter
*@m2: another filter.
*
* Removes all links between m1 and m2.
*
*Returns: 0 if one more link have been removed, -1 if not.
**/
gint ms_filter_remove_links(MSFilter *m1, MSFilter *m2)
{
int i,j;
int removed=-1;
MSQueue *qo;
MSFifo *fo;
/* takes all outputs of m1, and removes the one that goes to m2 */
if (m1->outqueues!=NULL){
for (i=0;i<MS_FILTER_GET_CLASS(m1)->max_qoutputs;i++)
{
qo=m1->outqueues[i];
if (qo!=NULL){
MSFilter *rmf;
/* test if the queue connects to m2 */
rmf=(MSFilter*)qo->next_data;
if (rmf==m2){
j=find_iq(rmf,qo);
if (j==-1) g_error("Could not find input queue: impossible case.");
ms_filter_unlink(m1,i,m2,j,LINK_QUEUE);
removed=0;
}
}
}
}
if (m1->outfifos!=NULL){
for (i=0;i<MS_FILTER_GET_CLASS(m1)->max_foutputs;i++)
{
fo=m1->outfifos[i];
if (fo!=NULL){
MSFilter *rmf;
/* test if the queue connects to m2 */
rmf=(MSFilter*)fo->next_data;
if (rmf==m2){
j=find_if(rmf,fo);
if (j==-1) g_error("Could not find input fifo: impossible case.");
ms_filter_unlink(m1,i,m2,j,LINK_FIFO);
removed=0;
}
}
}
}
return removed;
}
/**
* ms_filter_fifos_have_data:
* @f: a #MSFilter object.
*
* Tells if the filter has enough data in its input fifos in order to be executed succesfully.
*
* Returns: 1 if it can be executed, 0 else.
*/
gint ms_filter_fifos_have_data(MSFilter *f)
{
gint i,j;
gint max_inputs=f->klass->max_finputs;
gint con_inputs=f->finputs;
MSFifo *fifo;
/* test fifos */
for(i=0,j=0; (i<max_inputs) && (j<con_inputs);i++)
{
fifo=f->infifos[i];
if (fifo!=NULL)
{
j++;
if (fifo->readsize==0) return 0;
if (fifo->readsize>=f->r_mingran) return 1;
}
}
return 0;
}
/**
* ms_filter_queues_have_data:
* @f: a #MSFilter object.
*
* Tells if the filter has enough data in its input queues in order to be executed succesfully.
*
* Returns: 1 if it can be executed, 0 else.
*/
gint ms_filter_queues_have_data(MSFilter *f)
{
gint i,j;
gint max_inputs=f->klass->max_qinputs;
gint con_inputs=f->qinputs;
MSQueue *q;
/* test queues */
for(i=0,j=0; (i<max_inputs) && (j<con_inputs);i++)
{
q=f->inqueues[i];
if (q!=NULL)
{
j++;
if (ms_queue_can_get(q)) return 1;
}
}
return 0;
}
void ms_filter_destroy(MSFilter *f)
{
/* first check if the filter is disconnected from any others */
g_return_if_fail(f->finputs==0);
g_return_if_fail(f->foutputs==0);
g_return_if_fail(f->qinputs==0);
g_return_if_fail(f->qoutputs==0);
f->klass->destroy(f);
}
GList *filter_list=NULL;
void ms_filter_register(MSFilterInfo *info)
{
gpointer tmp;
tmp=g_list_find(filter_list,info);
if (tmp==NULL) filter_list=g_list_append(filter_list,(gpointer)info);
}
void ms_filter_unregister(MSFilterInfo *info)
{
filter_list=g_list_remove(filter_list,(gpointer)info);
}
static gint compare_names(gpointer info, gpointer name)
{
MSFilterInfo *i=(MSFilterInfo*) info;
return (strcmp(i->name,name));
}
MSFilterInfo * ms_filter_get_by_name(const gchar *name)
{
GList *elem=g_list_find_custom(filter_list,
(gpointer)name,(GCompareFunc)compare_names);
if (elem!=NULL){
return (MSFilterInfo*)elem->data;
}
return NULL;
}
MSFilter * ms_filter_new_with_name(const gchar *name)
{
MSFilterInfo *info=ms_filter_get_by_name(name);
if (info!=NULL) return info->constructor();
g_warning("ms_filter_new_with_name: no filter named %s found.",name);
return NULL;
}
/* find the first codec in the left part of the stream */
MSFilter * ms_filter_search_upstream_by_type(MSFilter *f,MSFilterType type)
{
MSFilter *tmp=f;
MSFilterInfo *info;
if ((tmp->infifos!=NULL) && (tmp->infifos[0]!=NULL)){
tmp=(MSFilter*) tmp->infifos[0]->prev_data;
while(1){
info=MS_FILTER_GET_CLASS(tmp)->info;
if (info!=NULL){
if ( (info->type==type) ){
return tmp;
}
}
if ((tmp->infifos!=NULL) && (tmp->infifos[0]!=NULL))
tmp=(MSFilter*) tmp->infifos[0]->prev_data;
else break;
}
}
tmp=f;
if ((tmp->inqueues!=NULL) && (tmp->inqueues[0]!=NULL)){
tmp=(MSFilter*) tmp->inqueues[0]->prev_data;
while(1){
info=MS_FILTER_GET_CLASS(tmp)->info;
if (info!=NULL){
if ( (info->type==type)){
return tmp;
}
}else g_warning("ms_filter_search_upstream_by_type: filter %s has no info."
,MS_FILTER_GET_CLASS(tmp)->name);
if ((tmp->inqueues!=NULL) && (tmp->inqueues[0]!=NULL))
tmp=(MSFilter*) tmp->inqueues[0]->prev_data;
else break;
}
}
return NULL;
}
int ms_filter_set_property(MSFilter *f, MSFilterProperty prop,void *value)
{
if (f->klass->set_property!=NULL){
return f->klass->set_property(f,prop,value);
}
return 0;
}
int ms_filter_get_property(MSFilter *f, MSFilterProperty prop,void *value)
{
if (f->klass->get_property!=NULL){
return f->klass->get_property(f,prop,value);
}
return -1;
}
void ms_filter_set_notify_func(MSFilter* filter,MSFilterNotifyFunc func, gpointer userdata)
{
filter->notify_event=func;
filter->userdata=userdata;
}
void ms_filter_notify_event(MSFilter *filter,gint event, gpointer arg)
{
if (filter->notify_event!=NULL){
filter->notify_event(filter,event,arg,filter->userdata);
}
}
void swap_buffer(gchar *buffer, gint len)
{
int i;
gchar tmp;
for (i=0;i<len;i+=2){
tmp=buffer[i];
buffer[i]=buffer[i+1];
buffer[i+1]=tmp;
}
}

View file

@ -1,202 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSFILTER_H
#define MSFILTER_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_GLIB
#include <glib.h>
#else
#undef VERSION
#undef PACKAGE
#include <uglib.h>
#endif
#include <string.h>
#include "msutils.h"
#include "msfifo.h"
#include "msqueue.h"
struct _MSFilter;
/*this is the abstract object and class for all filter types*/
typedef gint (*MSFilterNotifyFunc)(struct _MSFilter*, gint event, gpointer arg, gpointer userdata);
struct _MSFilter
{
struct _MSFilterClass *klass;
GMutex *lock;
guchar finputs; /* number of connected fifo inputs*/
guchar foutputs; /* number of connected fifo outputs*/
guchar qinputs; /* number of connected queue inputs*/
guchar qoutputs; /* number of connected queue outputs*/
gint min_fifo_size; /* set when linking*/
gint r_mingran; /* read minimum granularity (for fifos).
It can be zero so that the filter can accept any size of reading data*/
MSFifo **infifos; /*pointer to a table of pointer to input fifos*/
MSFifo **outfifos; /*pointer to a table of pointer to output fifos*/
MSQueue **inqueues; /*pointer to a table of pointer to input queues*/
MSQueue **outqueues; /*pointer to a table of pointer to output queues*/
MSFilterNotifyFunc notify_event;
gpointer userdata;
};
typedef struct _MSFilter MSFilter;
typedef enum{
MS_FILTER_PROPERTY_FREQ, /* value is int */
MS_FILTER_PROPERTY_BITRATE, /*value is int */
MS_FILTER_PROPERTY_CHANNELS,/*value is int */
MS_FILTER_PROPERTY_FMTP /* value is string */
}MSFilterProperty;
#define MS_FILTER_PROPERTY_STRING_MAX_SIZE 256
typedef MSFilter * (*MSFilterNewFunc)(void);
typedef void (*MSFilterProcessFunc)(MSFilter *);
typedef void (*MSFilterDestroyFunc)(MSFilter *);
typedef int (*MSFilterPropertyFunc)(MSFilter *,int ,void*);
typedef void (*MSFilterSetupFunc)(MSFilter *, void *); /*2nd arg is the sync */
typedef struct _MSFilterClass
{
struct _MSFilterInfo *info; /*pointer to a filter_info */
gchar *name;
guchar max_finputs; /* maximum number of fifo inputs*/
guchar max_foutputs; /* maximum number of fifo outputs*/
guchar max_qinputs; /* maximum number of queue inputs*/
guchar max_qoutputs; /* maximum number of queue outputs*/
gint r_maxgran; /* read maximum granularity (for fifos)*/
gint w_maxgran; /* write maximum granularity (for fifos)*/
gint r_offset; /* size of kept samples behind read pointer (for fifos)*/
gint w_offset; /* size of kept samples behind write pointer (for fifos)*/
MSFilterPropertyFunc set_property;
MSFilterPropertyFunc get_property;
MSFilterSetupFunc setup; /* called when attaching to sync */
void (*process)(MSFilter *filter);
MSFilterSetupFunc unsetup; /* called when detaching from sync */
void (*destroy)(MSFilter *filter);
guint attributes;
#define FILTER_HAS_FIFOS (0x0001)
#define FILTER_HAS_QUEUES (0x0001<<1)
#define FILTER_IS_SOURCE (0x0001<<2)
#define FILTER_IS_SINK (0x0001<<3)
#define FILTER_CAN_SYNC (0x0001<<4)
guint ref_count; /*number of object using the class*/
} MSFilterClass;
#define MS_FILTER(obj) ((MSFilter*)obj)
#define MS_FILTER_CLASS(klass) ((MSFilterClass*)klass)
#define MS_FILTER_GET_CLASS(obj) ((MSFilterClass*)((MS_FILTER(obj)->klass)))
void ms_filter_class_init(MSFilterClass *filterclass);
void ms_filter_init(MSFilter *filter);
#define ms_filter_class_set_attr(filter,flag) ((filter)->attributes|=(flag))
#define ms_filter_class_unset_attr(filter,flag) ((filter)->attributes&=~(flag))
#define ms_filter_class_set_name(__klass,__name) (__klass)->name=g_strdup((__name))
#define ms_filter_class_set_info(_klass,_info) (_klass)->info=(_info)
/* public*/
#define ms_filter_process(filter) ((filter)->klass->process((filter)))
#define ms_filter_lock(filter) g_mutex_lock((filter)->lock)
#define ms_filter_unlock(filter) g_mutex_unlock((filter)->lock)
/* low level connect functions */
int ms_filter_link(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2, gint linktype);
int ms_filter_unlink(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2,gint linktype);
/* high level connect functions */
int ms_filter_add_link(MSFilter *m1, MSFilter *m2);
int ms_filter_remove_links(MSFilter *m1, MSFilter *m2);
void ms_filter_set_notify_func(MSFilter* filter,MSFilterNotifyFunc func, gpointer userdata);
void ms_filter_notify_event(MSFilter *filter,gint event, gpointer arg);
int ms_filter_set_property(MSFilter *f,MSFilterProperty property, void *value);
int ms_filter_get_property(MSFilter *f,MSFilterProperty property, void *value);
gint ms_filter_fifos_have_data(MSFilter *f);
gint ms_filter_queues_have_data(MSFilter *f);
void ms_filter_uninit(MSFilter *obj);
void ms_filter_destroy(MSFilter *f);
#define ms_filter_get_mingran(f) ((f)->r_mingran)
#define ms_filter_set_mingran(f,gran) ((f)->r_mingran=(gran))
#define LINK_DEFAULT 0
#define LINK_FIFO 1
#define LINK_QUEUE 2
#define MSFILTER_VERSION(a,b,c) (((a)<<2)|((b)<<1)|(c))
enum _MSFilterType
{
MS_FILTER_DISK_IO,
MS_FILTER_AUDIO_CODEC,
MS_FILTER_VIDEO_CODEC,
MS_FILTER_NET_IO,
MS_FILTER_VIDEO_IO,
MS_FILTER_AUDIO_IO,
MS_FILTER_OTHER
};
typedef enum _MSFilterType MSFilterType;
/* find the first codec in the left part of the stream */
MSFilter * ms_filter_search_upstream_by_type(MSFilter *f,MSFilterType type);
struct _MSFilterInfo
{
gchar *name;
gint version;
MSFilterType type;
MSFilterNewFunc constructor;
char *description; /*some textual information*/
};
typedef struct _MSFilterInfo MSFilterInfo;
void ms_filter_register(MSFilterInfo *finfo);
void ms_filter_unregister(MSFilterInfo *finfo);
MSFilterInfo * ms_filter_get_by_name(const gchar *name);
MSFilter * ms_filter_new_with_name(const gchar *name);
extern GList *filter_list;
#define MS_FILTER_INFO(obj) ((MSFilterInfo*)obj)
void swap_buffer(gchar *buffer, gint len);
#endif

View file

@ -1,82 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msnosync.h"
static MSNoSyncClass *ms_nosync_class=NULL;
void ms_nosync_init(MSNoSync *sync)
{
ms_sync_init(MS_SYNC(sync));
MS_SYNC(sync)->attached_filters=sync->filters;
memset(sync->filters,0,MSNOSYNC_MAX_FILTERS*sizeof(MSFilter*));
MS_SYNC(sync)->samples_per_tick=160;
sync->started=0;
}
void ms_nosync_class_init(MSNoSyncClass *klass)
{
ms_sync_class_init(MS_SYNC_CLASS(klass));
MS_SYNC_CLASS(klass)->max_filters=MSNOSYNC_MAX_FILTERS;
MS_SYNC_CLASS(klass)->synchronize=(MSSyncSyncFunc)ms_nosync_synchronize;
MS_SYNC_CLASS(klass)->destroy=(MSSyncDestroyFunc)ms_nosync_destroy;
/* no need to overload these function*/
MS_SYNC_CLASS(klass)->attach=ms_sync_attach_generic;
MS_SYNC_CLASS(klass)->detach=ms_sync_detach_generic;
}
void ms_nosync_destroy(MSNoSync *nosync)
{
g_free(nosync);
}
/* the synchronization function that does nothing*/
void ms_nosync_synchronize(MSNoSync *nosync)
{
gint32 time;
if (nosync->started==0){
gettimeofday(&nosync->start,NULL);
nosync->started=1;
}
gettimeofday(&nosync->current,NULL);
MS_SYNC(nosync)->ticks++;
/* update the time, we are supposed to work at 8000 Hz */
time=((nosync->current.tv_sec-nosync->start.tv_sec)*1000) +
((nosync->current.tv_usec-nosync->start.tv_usec)/1000);
MS_SYNC(nosync)->time=time;
return;
}
MSSync *ms_nosync_new()
{
MSNoSync *nosync;
nosync=g_malloc(sizeof(MSNoSync));
ms_nosync_init(nosync);
if (ms_nosync_class==NULL)
{
ms_nosync_class=g_new(MSNoSyncClass,1);
ms_nosync_class_init(ms_nosync_class);
}
MS_SYNC(nosync)->klass=MS_SYNC_CLASS(ms_nosync_class);
return(MS_SYNC(nosync));
}

View file

@ -1,60 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mssync.h"
#include <sys/time.h>
#define MSNOSYNC_MAX_FILTERS 10
/* MSNoSync derivates from MSSync base class*/
typedef struct _MSNoSync
{
/* the MSSync must be the first field of the object in order to the object mechanism to work*/
MSSync sync;
MSFilter *filters[MSNOSYNC_MAX_FILTERS];
int started;
struct timeval start,current;
} MSNoSync;
typedef struct _MSNoSyncClass
{
/* the MSSyncClass must be the first field of the class in order to the class mechanism to work*/
MSSyncClass parent_class;
} MSNoSyncClass;
/*private*/
void ms_nosync_init(MSNoSync *sync);
void ms_nosync_class_init(MSNoSyncClass *sync);
void ms_nosync_destroy(MSNoSync *nosync);
void ms_nosync_synchronize(MSNoSync *nosync);
/*public*/
/* casts a MSSync object into a MSNoSync */
#define MS_NOSYNC(sync) ((MSNoSync*)(sync))
/* casts a MSSync class into a MSNoSync class */
#define MS_NOSYNC_CLASS(klass) ((MSNoSyncClass*)(klass))
MSSync *ms_nosync_new();

View file

@ -1,150 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msossread.h"
#include "mssync.h"
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
MSFilterInfo oss_read_info={
"OSS read",
0,
MS_FILTER_AUDIO_IO,
ms_oss_read_new,
NULL
};
static MSOssReadClass *msossreadclass=NULL;
MSFilter * ms_oss_read_new()
{
MSOssRead *w;
if (msossreadclass==NULL)
{
msossreadclass=g_new(MSOssReadClass,1);
ms_oss_read_class_init( msossreadclass );
}
w=g_new(MSOssRead,1);
MS_FILTER(w)->klass=MS_FILTER_CLASS(msossreadclass);
ms_oss_read_init(w);
return(MS_FILTER(w));
}
/* FOR INTERNAL USE*/
void ms_oss_read_init(MSOssRead *w)
{
ms_sound_read_init(MS_SOUND_READ(w));
MS_FILTER(w)->outfifos=w->f_outputs;
MS_FILTER(w)->outfifos[0]=NULL;
w->devid=0;
w->sndcard=NULL;
w->freq=8000;
}
gint ms_oss_read_set_property(MSOssRead *f,MSFilterProperty prop, void *value)
{
switch(prop){
case MS_FILTER_PROPERTY_FREQ:
f->freq=((gint*)value)[0];
break;
default:
break;
}
return 0;
}
void ms_oss_read_class_init(MSOssReadClass *klass)
{
ms_sound_read_class_init(MS_SOUND_READ_CLASS(klass));
MS_FILTER_CLASS(klass)->max_foutputs=1; /* one fifo output only */
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_oss_read_setup;
MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_oss_read_stop;
MS_FILTER_CLASS(klass)->process= (MSFilterProcessFunc)ms_oss_read_process;
MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_oss_read_set_property;
MS_FILTER_CLASS(klass)->destroy= (MSFilterDestroyFunc)ms_oss_read_destroy;
MS_FILTER_CLASS(klass)->w_maxgran=MS_OSS_READ_MAX_GRAN;
MS_FILTER_CLASS(klass)->info=&oss_read_info;
MS_SOUND_READ_CLASS(klass)->set_device=(gint (*)(MSSoundRead*,gint))ms_oss_read_set_device;
MS_SOUND_READ_CLASS(klass)->start=(void (*)(MSSoundRead*))ms_oss_read_start;
MS_SOUND_READ_CLASS(klass)->stop=(void (*)(MSSoundRead*))ms_oss_read_stop;
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"OssRead");
//ms_filter_class_set_attr( MS_FILTER_CLASS(klass),FILTER_CAN_SYNC|FILTER_IS_SOURCE);
}
void ms_oss_read_destroy( MSOssRead *obj)
{
g_free(obj);
}
void ms_oss_read_process(MSOssRead *f)
{
MSFifo *fifo;
char *p;
fifo=f->f_outputs[0];
g_return_if_fail(f->sndcard!=NULL);
g_return_if_fail(f->gran>0);
if (snd_card_can_read(f->sndcard)){
int got;
ms_fifo_get_write_ptr(fifo,f->gran,(void**)&p);
g_return_if_fail(p!=NULL);
got=snd_card_read(f->sndcard,p,f->gran);
if (got>=0 && got!=f->gran) ms_fifo_update_write_ptr(fifo,got);
}
}
void ms_oss_read_start(MSOssRead *r)
{
g_return_if_fail(r->devid!=-1);
r->sndcard=snd_card_manager_get_card(snd_card_manager,r->devid);
g_return_if_fail(r->sndcard!=NULL);
/* open the device for an audio telephony signal with minimum latency */
snd_card_open_r(r->sndcard,16,0,r->freq);
r->gran=(512*r->freq)/8000;
}
void ms_oss_read_stop(MSOssRead *w)
{
g_return_if_fail(w->devid!=-1);
g_return_if_fail(w->sndcard!=NULL);
snd_card_close_r(w->sndcard);
w->sndcard=NULL;
}
void ms_oss_read_setup(MSOssRead *f, MSSync *sync)
{
f->sync=sync;
ms_oss_read_start(f);
}
gint ms_oss_read_set_device(MSOssRead *r,gint devid)
{
r->devid=devid;
return 0;
}

View file

@ -1,77 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSOSSREAD_H
#define MSOSSREAD_H
#include "mssoundread.h"
#include "sndcard.h"
#include "mssync.h"
/*this is the class that implements oss writing sink filter*/
#define MS_OSS_READ_MAX_INPUTS 1 /* max output per filter*/
#define MS_OSS_READ_MAX_GRAN (512*2) /* the maximum granularity*/
struct _MSOssRead
{
/* the MSOssRead derivates from MSSoundRead so the MSSoundRead object MUST be the first of the MSOssRead object
in order to the object mechanism to work*/
MSSoundRead filter;
MSFifo *f_outputs[MS_OSS_READ_MAX_INPUTS];
MSSync *sync;
SndCard *sndcard;
gint freq;
gint devid; /* the sound device id it depends on*/
gint gran;
gint flags;
#define START_REQUESTED 1
#define STOP_REQUESTED 2
};
typedef struct _MSOssRead MSOssRead;
struct _MSOssReadClass
{
/* the MSOssRead derivates from MSSoundRead, so the MSSoundRead class MUST be the first of the MSOssRead class
in order to the class mechanism to work*/
MSSoundReadClass parent_class;
};
typedef struct _MSOssReadClass MSOssReadClass;
/* PUBLIC */
#define MS_OSS_READ(filter) ((MSOssRead*)(filter))
#define MS_OSS_READ_CLASS(klass) ((MSOssReadClass*)(klass))
MSFilter * ms_oss_read_new(void);
gint ms_oss_read_set_device(MSOssRead *w,gint devid);
void ms_oss_read_start(MSOssRead *w);
void ms_oss_read_stop(MSOssRead *w);
/* FOR INTERNAL USE*/
void ms_oss_read_init(MSOssRead *r);
void ms_oss_read_class_init(MSOssReadClass *klass);
void ms_oss_read_destroy( MSOssRead *obj);
void ms_oss_read_process(MSOssRead *f);
void ms_oss_read_setup(MSOssRead *f, MSSync *sync);
#endif

View file

@ -1,249 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msosswrite.h"
#include "mssync.h"
#include <unistd.h>
#include <math.h>
MSFilterInfo oss_write_info={
"OSS write",
0,
MS_FILTER_OTHER,
ms_oss_write_new,
NULL
};
static MSOssWriteClass *msosswriteclass=NULL;
MSFilter * ms_oss_write_new()
{
MSOssWrite *w;
if (msosswriteclass==NULL)
{
msosswriteclass=g_new(MSOssWriteClass,1);
ms_oss_write_class_init( msosswriteclass );
}
w=g_new(MSOssWrite,1);
MS_FILTER(w)->klass=MS_FILTER_CLASS(msosswriteclass);
ms_oss_write_init(w);
return(MS_FILTER(w));
}
/* FOR INTERNAL USE*/
void ms_oss_write_init(MSOssWrite *w)
{
ms_sound_write_init(MS_SOUND_WRITE(w));
MS_FILTER(w)->infifos=w->f_inputs;
MS_FILTER(w)->infifos[0]=NULL;
MS_FILTER(w)->r_mingran=512; /* very few cards can do that...*/
w->devid=0;
w->sndcard=NULL;
w->freq=8000;
w->channels=1;
w->dtmf_time=-1;
}
gint ms_oss_write_set_property(MSOssWrite *f,MSFilterProperty prop, void *value)
{
switch(prop){
case MS_FILTER_PROPERTY_FREQ:
f->freq=((gint*)value)[0];
break;
case MS_FILTER_PROPERTY_CHANNELS:
f->channels=((gint*)value)[0];
break;
default:
break;
}
return 0;
}
void ms_oss_write_class_init(MSOssWriteClass *klass)
{
ms_sound_write_class_init(MS_SOUND_WRITE_CLASS(klass));
MS_FILTER_CLASS(klass)->max_finputs=1; /* one fifo input only */
MS_FILTER_CLASS(klass)->r_maxgran=MS_OSS_WRITE_DEF_GRAN;
MS_FILTER_CLASS(klass)->process= (MSFilterProcessFunc)ms_oss_write_process;
MS_FILTER_CLASS(klass)->destroy= (MSFilterDestroyFunc)ms_oss_write_destroy;
MS_FILTER_CLASS(klass)->setup= (MSFilterSetupFunc)ms_oss_write_setup;
MS_FILTER_CLASS(klass)->unsetup= (MSFilterSetupFunc)ms_oss_write_stop;
MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_oss_write_set_property;
MS_FILTER_CLASS(klass)->info=&oss_write_info;
MS_SOUND_WRITE_CLASS(klass)->set_device=(gint (*)(MSSoundWrite*,gint))ms_oss_write_set_device;
MS_SOUND_WRITE_CLASS(klass)->start=(void (*)(MSSoundWrite*))ms_oss_write_start;
MS_SOUND_WRITE_CLASS(klass)->stop=(void (*)(MSSoundWrite*))ms_oss_write_stop;
MS_SOUND_WRITE_CLASS(klass)->set_level=(void (*)(MSSoundWrite*, gint))ms_oss_write_set_level;
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"OssWrite");
}
void ms_oss_write_destroy( MSOssWrite *obj)
{
g_free(obj);
}
void ms_oss_write_process(MSOssWrite *f)
{
MSFifo *fifo;
void *p;
int i;
gint gran=ms_filter_get_mingran(MS_FILTER(f));
/* always consume something */
fifo=f->f_inputs[0];
ms_fifo_get_read_ptr(fifo,gran,&p);
if (p==NULL) {
g_warning("Not enough data: gran=%i.",gran);
return;
}
g_return_if_fail(f->sndcard!=NULL);
if (f->dtmf_time!=-1){
gint16 *buf=(gint16*)p;
/* generate a DTMF*/
for(i=0;i<gran/2;i++){
buf[i]=(gint16)(10000.0*sin(2*M_PI*(double)f->dtmf_time*f->lowfreq));
buf[i]+=(gint16)(10000.0*sin(2*M_PI*(double)f->dtmf_time*f->highfreq));
f->dtmf_time++;
//printf("buf[%i]=%i\n",i,buf[i]);
}
if (f->dtmf_time>f->dtmf_duration) f->dtmf_time=-1; /*finished*/
}
snd_card_write(f->sndcard,p,gran);
}
void ms_oss_write_start(MSOssWrite *w)
{
//gint bsize;
g_return_if_fail(w->devid!=-1);
w->sndcard=snd_card_manager_get_card(snd_card_manager,w->devid);
g_return_if_fail(w->sndcard!=NULL);
/* open the device for an audio telephony signal with minimum latency */
snd_card_open_w(w->sndcard,16,w->channels==2,w->freq);
w->bsize=snd_card_get_bsize(w->sndcard);
//MS_FILTER(w)->r_mingran=w->bsize;
//ms_sync_set_samples_per_tick(MS_FILTER(w)->sync,bsize);
}
void ms_oss_write_stop(MSOssWrite *w)
{
g_return_if_fail(w->devid!=-1);
g_return_if_fail(w->sndcard!=NULL);
snd_card_close_w(w->sndcard);
w->sndcard=NULL;
}
void ms_oss_write_set_level(MSOssWrite *w,gint a)
{
}
gint ms_oss_write_set_device(MSOssWrite *w, gint devid)
{
w->devid=devid;
return 0;
}
void ms_oss_write_setup(MSOssWrite *r)
{
//g_message("starting MSOssWrite..");
ms_oss_write_start(r);
}
void ms_oss_write_play_dtmf(MSOssWrite *w, char dtmf){
w->dtmf_duration=0.1*w->freq;
switch(dtmf){
case '0':
w->lowfreq=941;
w->highfreq=1336;
break;
case '1':
w->lowfreq=697;
w->highfreq=1209;
break;
case '2':
w->lowfreq=697;
w->highfreq=1336;
break;
case '3':
w->lowfreq=697;
w->highfreq=1477;
break;
case '4':
w->lowfreq=770;
w->highfreq=1209;
break;
case '5':
w->lowfreq=770;
w->highfreq=1336;
break;
case '6':
w->lowfreq=770;
w->highfreq=1477;
break;
case '7':
w->lowfreq=852;
w->highfreq=1209;
break;
case '8':
w->lowfreq=852;
w->highfreq=1336;
break;
case '9':
w->lowfreq=852;
w->highfreq=1477;
break;
case '*':
w->lowfreq=941;
w->highfreq=1209;
break;
case '#':
w->lowfreq=941;
w->highfreq=1477;
break;
case 'A':
w->lowfreq=697;
w->highfreq=1633;
break;
case 'B':
w->lowfreq=770;
w->highfreq=1633;
break;
case 'C':
w->lowfreq=852;
w->highfreq=1633;
break;
case 'D':
w->lowfreq=941;
w->highfreq=1633;
break;
default:
g_warning("Not a dtmf key.");
return;
}
w->lowfreq=w->lowfreq/w->freq;
w->highfreq=w->highfreq/w->freq;
w->dtmf_time=0;
}

View file

@ -1,78 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSOSSWRITE_H
#define MSOSSWRITE_H
#include "mssoundwrite.h"
#include "sndcard.h"
/*this is the class that implements oss writing sink filter*/
#define MS_OSS_WRITE_MAX_INPUTS 1 /* max output per filter*/
#define MS_OSS_WRITE_DEF_GRAN (512*2) /* the default granularity*/
struct _MSOssWrite
{
/* the MSOssWrite derivates from MSSoundWrite, so the MSSoundWrite object MUST be the first of the MSOssWrite object
in order to the object mechanism to work*/
MSSoundWrite filter;
MSFifo *f_inputs[MS_OSS_WRITE_MAX_INPUTS];
gint devid; /* the sound device id it depends on*/
SndCard *sndcard;
gint bsize;
gint freq;
gint channels;
gdouble lowfreq;
gdouble highfreq;
gint dtmf_time;
gint dtmf_duration;
};
typedef struct _MSOssWrite MSOssWrite;
struct _MSOssWriteClass
{
/* the MSOssWrite derivates from MSSoundWrite, so the MSSoundWrite class MUST be the first of the MSOssWrite class
in order to the class mechanism to work*/
MSSoundWriteClass parent_class;
};
typedef struct _MSOssWriteClass MSOssWriteClass;
/* PUBLIC */
#define MS_OSS_WRITE(filter) ((MSOssWrite*)(filter))
#define MS_OSS_WRITE_CLASS(klass) ((MSOssWriteClass*)(klass))
MSFilter * ms_oss_write_new(void);
gint ms_oss_write_set_device(MSOssWrite *w,gint devid);
void ms_oss_write_start(MSOssWrite *w);
void ms_oss_write_stop(MSOssWrite *w);
void ms_oss_write_set_level(MSOssWrite *w, gint level);
void ms_oss_write_play_dtmf(MSOssWrite *w, char dtmf);
/* FOR INTERNAL USE*/
void ms_oss_write_init(MSOssWrite *r);
void ms_oss_write_setup(MSOssWrite *r);
void ms_oss_write_class_init(MSOssWriteClass *klass);
void ms_oss_write_destroy( MSOssWrite *obj);
void ms_oss_write_process(MSOssWrite *f);
#endif

View file

@ -1,91 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a dispatcher of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msqdispatcher.h"
static MSQdispatcherClass *ms_qdispatcher_class=NULL;
MSFilter * ms_qdispatcher_new(void)
{
MSQdispatcher *obj;
obj=g_malloc(sizeof(MSQdispatcher));
if (ms_qdispatcher_class==NULL){
ms_qdispatcher_class=g_malloc0(sizeof(MSQdispatcherClass));
ms_qdispatcher_class_init(ms_qdispatcher_class);
}
MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_qdispatcher_class);
ms_qdispatcher_init(obj);
return MS_FILTER(obj);
}
void ms_qdispatcher_init(MSQdispatcher *obj)
{
ms_filter_init(MS_FILTER(obj));
MS_FILTER(obj)->inqueues=obj->q_inputs;
MS_FILTER(obj)->outqueues=obj->q_outputs;
memset(obj->q_inputs,0,sizeof(MSQueue*)*MS_QDISPATCHER_MAX_INPUTS);
memset(obj->q_outputs,0,sizeof(MSQueue*)*MS_QDISPATCHER_MAX_OUTPUTS);
}
void ms_qdispatcher_class_init(MSQdispatcherClass *klass)
{
MSFilterClass *parent_class=MS_FILTER_CLASS(klass);
ms_filter_class_init(parent_class);
ms_filter_class_set_name(parent_class,"qdispatcher");
parent_class->max_qinputs=MS_QDISPATCHER_MAX_INPUTS;
parent_class->max_qoutputs=MS_QDISPATCHER_MAX_OUTPUTS;
parent_class->destroy=(MSFilterDestroyFunc)ms_qdispatcher_destroy;
parent_class->process=(MSFilterProcessFunc)ms_qdispatcher_process;
}
void ms_qdispatcher_destroy( MSQdispatcher *obj)
{
g_free(obj);
}
void ms_qdispatcher_process(MSQdispatcher *obj)
{
gint i;
MSQueue *inq=obj->q_inputs[0];
if (inq!=NULL){
MSQueue *outq;
MSMessage *m1,*m2;
while ( (m1=ms_queue_get(inq))!=NULL){
/* dispatch incoming messages to output queues */
for (i=0;i<MS_QDISPATCHER_MAX_OUTPUTS;i++){
outq=obj->q_outputs[i];
if (outq!=NULL){
m2=ms_message_dup(m1);
ms_queue_put(outq,m2);
}
}
ms_message_destroy(m1);
}
}
}

View file

@ -1,60 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a dispatcher of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSQDISPATCHER_H
#define MSQDISPATCHER_H
#include "msfilter.h"
/*this is the class that implements a qdispatcher filter*/
#define MS_QDISPATCHER_MAX_INPUTS 1
#define MS_QDISPATCHER_MAX_OUTPUTS 5
typedef struct _MSQdispatcher
{
/* the MSQdispatcher derivates from MSFilter, so the MSFilter object MUST be the first of the MSQdispatcher object
in order to the object mechanism to work*/
MSFilter filter;
MSQueue *q_inputs[MS_QDISPATCHER_MAX_INPUTS];
MSQueue *q_outputs[MS_QDISPATCHER_MAX_OUTPUTS];
} MSQdispatcher;
typedef struct _MSQdispatcherClass
{
/* the MSQdispatcher derivates from MSFilter, so the MSFilter class MUST be the first of the MSQdispatcher class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSQdispatcherClass;
/* PUBLIC */
#define MS_QDISPATCHER(filter) ((MSQdispatcher*)(filter))
#define MS_QDISPATCHER_CLASS(klass) ((MSQdispatcherClass*)(klass))
MSFilter * ms_qdispatcher_new(void);
/* FOR INTERNAL USE*/
void ms_qdispatcher_init(MSQdispatcher *r);
void ms_qdispatcher_class_init(MSQdispatcherClass *klass);
void ms_qdispatcher_destroy( MSQdispatcher *obj);
void ms_qdispatcher_process(MSQdispatcher *r);
#endif

View file

@ -1,58 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msqueue.h"
#include <string.h>
MSQueue * ms_queue_new()
{
MSQueue *q=g_malloc(sizeof(MSQueue));
memset(q,0,sizeof(MSQueue));
return q;
}
MSMessage *ms_queue_get(MSQueue *q)
{
MSMessage *b=q->last;
if (b==NULL) return NULL;
q->last=b->prev;
if (b->prev==NULL) q->first=NULL; /* it was the only element of the queue*/
q->size--;
b->next=b->prev=NULL;
return(b);
}
void ms_queue_put(MSQueue *q, MSMessage *m)
{
MSMessage *mtmp=q->first;
g_return_if_fail(m!=NULL);
q->first=m;
m->next=mtmp;
if (mtmp!=NULL)
{
mtmp->prev=m;
}
else q->last=m; /* it was the first element of the q */
q->size++;
}
MSMessage *ms_queue_peek_last(MSQueue *q){
return q->last;
}

View file

@ -1,51 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSQUEUE_H
#define MSQUEUE_H
#include "msbuffer.h"
/* for the moment these are stupid queues limited to one element*/
typedef struct _MSQueue
{
MSMessage *first;
MSMessage *last;
gint size;
void *prev_data; /*user data, usually the writting filter*/
void *next_data; /* user data, usually the reading filter*/
}MSQueue;
MSQueue * ms_queue_new();
MSMessage *ms_queue_get(MSQueue *q);
void ms_queue_put(MSQueue *q, MSMessage *m);
MSMessage *ms_queue_peek_last(MSQueue *q);
#define ms_queue_can_get(q) ( (q)->size!=0 )
#define ms_queue_destroy(q) g_free(q)
#endif

View file

@ -1,186 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msread.h"
#include "mssync.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
static MSReadClass *ms_read_class=NULL;
gint ms_read_open(MSRead *r, gchar *name);
MSFilter * ms_read_new(char *name)
{
MSRead *r;
r=g_new(MSRead,1);
ms_read_init(r);
if (ms_read_class==NULL)
{
ms_read_class=g_new(MSReadClass,1);
ms_read_class_init(ms_read_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_read_class);
r->fd=-1;
if (name!=NULL) ms_read_open(r,name);
return(MS_FILTER(r));
}
gint ms_read_open(MSRead *r, gchar *name)
{
gint fd;
fd=open(name,O_RDONLY);
if (fd<0) {
r->fd=-1;
g_warning("ms_read_new: cannot open %s : %s",name,strerror(errno));
return -1;
}
r->fd=fd;
if (strstr(name,".wav")!=NULL){
/* skip the header */
lseek(fd,20,SEEK_SET);
#ifdef WORDS_BIGENDIAN
r->need_swap=1;
#else
r->need_swap=0;
#endif
}
r->state=MS_READ_STATE_STARTED;
return 0;
}
/* FOR INTERNAL USE*/
void ms_read_init(MSRead *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->outfifos=r->foutputs;
MS_FILTER(r)->outqueues=r->qoutputs;
memset(r->foutputs,0,sizeof(MSFifo*)*MSREAD_MAX_OUTPUTS);
memset(r->qoutputs,0,sizeof(MSQueue*)*MSREAD_MAX_OUTPUTS);
r->fd=-1;
r->gran=320;
r->state=MS_READ_STATE_STOPPED;
r->need_swap=0;
r->rate=8000;
}
gint ms_read_set_property(MSRead *f,MSFilterProperty prop, void *value)
{
switch(prop){
case MS_FILTER_PROPERTY_FREQ:
f->rate=((gint*)value)[0];
break;
default:
break;
}
return 0;
}
void ms_read_class_init(MSReadClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"dskreader");
ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE);
MS_FILTER_CLASS(klass)->max_foutputs=MSREAD_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->max_qoutputs=MSREAD_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->w_maxgran=MSREAD_DEF_GRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_read_destroy;
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_read_setup;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_read_process;
MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_read_set_property;
}
void ms_read_process(MSRead *r)
{
MSFifo *f;
MSQueue *q;
MSMessage *msg=NULL;
int err;
gint gran=r->gran;
void *p;
f=r->foutputs[0];
if ((f!=NULL) && (r->state==MS_READ_STATE_STARTED))
{
ms_fifo_get_write_ptr(f,gran,&p);
if (p!=NULL)
{
err=read(r->fd,p,gran);
if (err<0)
{
/* temp: */
g_warning("ms_read_process: failed to read: %s.\n",strerror(errno));
}
else if (err<gran){
ms_trace("ms_read_process: end of file.");
ms_filter_notify_event(MS_FILTER(r),MS_READ_EVENT_EOF,NULL);
r->state=MS_READ_STATE_STOPPED;
close(r->fd);
r->fd=-1;
}
if (r->need_swap) swap_buffer(p,gran);
}
}
/* process output queues*/
q=r->qoutputs[0];
if ((q!=NULL) && (r->fd>0))
{
msg=ms_message_new(r->gran);
err=read(r->fd,msg->data,r->gran);
if (err>0){
msg->size=err;
ms_queue_put(q,msg);
if (r->need_swap) swap_buffer(msg->data,r->gran);
}else{
ms_filter_notify_event(MS_FILTER(r),MS_READ_EVENT_EOF,NULL);
ms_trace("End of file reached.");
r->state=MS_READ_STATE_STOPPED;
}
}
}
void ms_read_destroy( MSRead *obj)
{
if (obj->fd!=0) close(obj->fd);
g_free(obj);
}
gint ms_read_close(MSRead *obj)
{
if (obj->fd!=0) {
close(obj->fd);
obj->fd=-1;
obj->state=MS_READ_STATE_STOPPED;
}
return 0;
}
void ms_read_setup(MSRead *r, MSSync *sync)
{
r->sync=sync;
r->gran=(r->rate*sync->interval/1000)*2;
}

View file

@ -1,80 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSREAD_H
#define MSREAD_H
#include "msfilter.h"
#include "mssync.h"
/*this is the class that implements file reading source filter*/
#define MSREAD_MAX_OUTPUTS 1 /* max output per filter*/
#define MSREAD_DEF_GRAN 640 /* the default granularity*/
typedef enum{
MS_READ_STATE_STARTED,
MS_READ_STATE_STOPPED,
MS_READ_STATE_EOF
}MSReadState;
typedef struct _MSRead
{
/* the MSRead derivates from MSFilter, so the MSFilter object MUST be the first of the MSRead object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *foutputs[MSREAD_MAX_OUTPUTS];
MSQueue *qoutputs[MSREAD_MAX_OUTPUTS];
MSSync *sync;
gint rate;
gint fd; /* the file descriptor of the file being read*/
gint gran; /*granularity*/ /* for use with queues */
gint need_swap;
gint state;
} MSRead;
typedef struct _MSReadClass
{
/* the MSRead derivates from MSFilter, so the MSFilter class MUST be the first of the MSRead class
in order to the class mechanism to work*/
MSFilterClass parent_class;
} MSReadClass;
/* PUBLIC */
#define MS_READ(filter) ((MSRead*)(filter))
#define MS_READ_CLASS(klass) ((MSReadClass*)(klass))
MSFilter * ms_read_new(char *name);
/* set the granularity for reading file on disk */
#define ms_read_set_bufsize(filter,sz) (filter)->gran=(sz)
/* FOR INTERNAL USE*/
void ms_read_init(MSRead *r);
void ms_read_class_init(MSReadClass *klass);
void ms_read_destroy( MSRead *obj);
void ms_read_process(MSRead *r);
void ms_read_setup(MSRead *r, MSSync *sync);
typedef enum{
MS_READ_EVENT_EOF /* end of file */
} MSReadEvent;
#endif

View file

@ -1,255 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msringplayer.h"
#include "mssync.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include "waveheader.h"
#define WAVE_HEADER_OFFSET sizeof(wave_header_t)
enum { PLAY_RING, PLAY_SILENCE};
static int supported_freq[6]={8000,11025,16000,22050,32000,44100};
gint ms_ring_player_set_property(MSRingPlayer *f,MSFilterProperty prop, void *value);
gint freq_is_supported(gint freq){
int i;
for (i=0;i<6;i++){
if (abs(supported_freq[i]-freq)<50) return supported_freq[i];
}
return 0;
}
static MSRingPlayerClass *ms_ring_player_class=NULL;
/**
* ms_ring_player_new:
* @name: The path to the 16-bit 8khz raw file to be played as a ring.
* @seconds: The number of seconds that separates two rings.
*
* Allocates a new MSRingPlayer object.
*
*
* Returns: a pointer the the object, NULL if name could not be open.
*/
MSFilter * ms_ring_player_new(char *name, gint seconds)
{
MSRingPlayer *r;
int fd=-1;
if ((name!=NULL) && (strlen(name)!=0))
{
fd=open(name,O_RDONLY);
if (fd<0)
{
g_warning("ms_ring_player_new: failed to open %s.\n",name);
return NULL;
}
}else {
g_warning("ms_ring_player_new: Bad file name");
return NULL;
}
r=g_new(MSRingPlayer,1);
ms_ring_player_init(r);
if (ms_ring_player_class==NULL)
{
ms_ring_player_class=g_new(MSRingPlayerClass,1);
ms_ring_player_class_init(ms_ring_player_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ring_player_class);
r->fd=fd;
r->silence=seconds;
r->freq=8000;
if (strstr(name,".wav")!=NULL){
wave_header_t header;
int freq,freq2;
/* read the header */
size_t ret = read(fd,&header,sizeof(wave_header_t));
assert( ret == sizeof(wave_header_t) );
freq=wave_header_get_rate(&header);
if ((freq2=freq_is_supported(freq))>0){
r->freq=freq2;
}else {
g_warning("Unsupported sampling rate %i",freq);
r->freq=8000;
}
r->channel=wave_header_get_channel(&header);
lseek(fd,WAVE_HEADER_OFFSET,SEEK_SET);
#ifdef WORDS_BIGENDIAN
r->need_swap=1;
#else
r->need_swap=0;
#endif
}
ms_ring_player_set_property(r, MS_FILTER_PROPERTY_FREQ,&r->freq);
r->state=PLAY_RING;
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_ring_player_init(MSRingPlayer *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->outfifos=r->foutputs;
MS_FILTER(r)->outqueues=r->qoutputs;
memset(r->foutputs,0,sizeof(MSFifo*)*MS_RING_PLAYER_MAX_OUTPUTS);
memset(r->qoutputs,0,sizeof(MSQueue*)*MS_RING_PLAYER_MAX_OUTPUTS);
r->fd=-1;
r->current_pos=0;
r->need_swap=0;
r->sync=NULL;
}
gint ms_ring_player_set_property(MSRingPlayer *f,MSFilterProperty prop, void *value)
{
switch(prop){
case MS_FILTER_PROPERTY_FREQ:
f->rate=((gint*)value)[0]*2;
f->silence_bytes=f->silence*f->rate;
if (f->sync!=NULL)
f->gran=(f->rate*f->sync->interval/1000)*2;
break;
default:
break;
}
return 0;
}
gint ms_ring_player_get_property(MSRingPlayer *f,MSFilterProperty prop, void *value)
{
switch(prop){
case MS_FILTER_PROPERTY_FREQ:
((gint*)value)[0]=f->freq;
break;
case MS_FILTER_PROPERTY_CHANNELS:
((gint*)value)[0]=f->channel;
break;
default:
break;
}
return 0;
}
gint ms_ring_player_get_sample_freq(MSRingPlayer *obj){
return obj->freq;
}
void ms_ring_player_class_init(MSRingPlayerClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ringplay");
ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE);
MS_FILTER_CLASS(klass)->max_foutputs=MS_RING_PLAYER_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->max_qoutputs=MS_RING_PLAYER_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->w_maxgran=MS_RING_PLAYER_DEF_GRAN;
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_ring_player_setup;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ring_player_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ring_player_process;
MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_ring_player_set_property;
MS_FILTER_CLASS(klass)->get_property=(MSFilterPropertyFunc)ms_ring_player_get_property;
}
void ms_ring_player_process(MSRingPlayer *r)
{
MSFifo *f;
gint err;
gint processed=0;
gint gran=r->gran;
char *p;
g_return_if_fail(gran>0);
/* process output fifos*/
f=r->foutputs[0];
ms_fifo_get_write_ptr(f,gran,(void**)&p);
g_return_if_fail(p!=NULL);
for (processed=0;processed<gran;){
switch(r->state){
case PLAY_RING:
err=read(r->fd,&p[processed],gran-processed);
if (err<0)
{
memset(&p[processed],0,gran-processed);
processed=gran;
g_warning("ms_ring_player_process: failed to read: %s.\n",strerror(errno));
return;
}
else if (err<gran)
{/* end of file */
r->current_pos=r->silence_bytes;
lseek(r->fd,WAVE_HEADER_OFFSET,SEEK_SET);
r->state=PLAY_SILENCE;
ms_filter_notify_event(MS_FILTER(r),MS_RING_PLAYER_END_OF_RING_EVENT,NULL);
}
if (r->need_swap) swap_buffer(&p[processed],err);
processed+=err;
break;
case PLAY_SILENCE:
err=gran-processed;
if (r->current_pos>err){
memset(&p[processed],0,err);
r->current_pos-=gran;
processed=gran;
}else{
memset(&p[processed],0,r->current_pos);
processed+=r->current_pos;
r->state=PLAY_RING;
}
break;
}
}
}
/**
* ms_ring_player_destroy:
* @obj: A valid MSRingPlayer object.
*
* Destroy a MSRingPlayer object.
*
*
*/
void ms_ring_player_destroy( MSRingPlayer *obj)
{
if (obj->fd!=0) close(obj->fd);
g_free(obj);
}
void ms_ring_player_setup(MSRingPlayer *r,MSSync *sync)
{
r->sync=sync;
r->gran=(r->rate*r->sync->interval/1000)*r->channel;
}

View file

@ -1,81 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSRINGPLAYER_H
#define MSRINGPLAYER_H
#include "msfilter.h"
#include "mssync.h"
/*this is the class that implements file reading source filter*/
#define MS_RING_PLAYER_MAX_OUTPUTS 1 /* max output per filter*/
#define MS_RING_PLAYER_DEF_GRAN 8192 /* the default granularity*/
#define MS_RING_PLAYER_END_OF_RING_EVENT 1
struct _MSRingPlayer
{
/* the MSRingPlayer derivates from MSFilter, so the MSFilter object MUST be the first of the MSRingPlayer object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *foutputs[MS_RING_PLAYER_MAX_OUTPUTS];
MSQueue *qoutputs[MS_RING_PLAYER_MAX_OUTPUTS];\
MSSync *sync;
gint gran;
gint freq;
gint rate;
gint channel; /* number of interleaved channels */
gint silence; /* silence time between each ring, in seconds */
gint state;
gint fd; /* the file descriptor of the file being read*/
gint silence_bytes; /*silence in number of bytes between each ring */
gint current_pos;
gint need_swap;
};
typedef struct _MSRingPlayer MSRingPlayer;
struct _MSRingPlayerClass
{
/* the MSRingPlayer derivates from MSFilter, so the MSFilter class MUST be the first of the MSRingPlayer class
in order to the class mechanism to work*/
MSFilterClass parent_class;
};
typedef struct _MSRingPlayerClass MSRingPlayerClass;
/* PUBLIC */
#define MS_RING_PLAYER(filter) ((MSRingPlayer*)(filter))
#define MS_RING_PLAYER_CLASS(klass) ((MSRingPlayerClass*)(klass))
MSFilter * ms_ring_player_new(char *name, gint seconds);
gint ms_ring_player_get_sample_freq(MSRingPlayer *obj);
/* FOR INTERNAL USE*/
void ms_ring_player_init(MSRingPlayer *r);
void ms_ring_player_class_init(MSRingPlayerClass *klass);
void ms_ring_player_destroy( MSRingPlayer *obj);
void ms_ring_player_process(MSRingPlayer *r);
#define ms_ring_player_set_bufsize(filter,sz) (filter)->gran=(sz)
void ms_ring_player_setup(MSRingPlayer *r,MSSync *sync);
#endif

View file

@ -1,182 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msrtprecv.h"
/* some utilities to convert mblk_t to MSMessage and vice-versa */
MSMessage *msgb_2_ms_message(mblk_t* mp){
MSMessage *msg;
MSBuffer *msbuf;
if (mp->b_datap->ref_count!=1) return NULL; /* cannot handle properly non-unique buffers*/
/* create a MSBuffer using the mblk_t buffer */
msg=ms_message_alloc();
msbuf=ms_buffer_new_with_buf(mp->b_datap->db_base,mp->b_datap->db_lim-mp->b_datap->db_base,
freemsg,mp);
ms_message_set_buf(msg,msbuf);
msg->size=mp->b_wptr-mp->b_rptr;
msg->data=mp->b_rptr;
return msg;
}
static MSRtpRecvClass *ms_rtp_recv_class=NULL;
MSFilter * ms_rtp_recv_new(void)
{
MSRtpRecv *r;
r=g_new(MSRtpRecv,1);
ms_rtp_recv_init(r);
if (ms_rtp_recv_class==NULL)
{
ms_rtp_recv_class=g_new0(MSRtpRecvClass,1);
ms_rtp_recv_class_init(ms_rtp_recv_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_rtp_recv_class);
return(MS_FILTER(r));
}
/* FOR INTERNAL USE*/
void ms_rtp_recv_init(MSRtpRecv *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->outfifos=r->f_outputs;
MS_FILTER(r)->outqueues=r->q_outputs;
memset(r->f_outputs,0,sizeof(MSFifo*)*MSRTPRECV_MAX_OUTPUTS);
memset(r->q_outputs,0,sizeof(MSFifo*)*MSRTPRECV_MAX_OUTPUTS);
r->rtpsession=NULL;
r->stream_started=0;
r->ignore=FALSE;
r->payload_expected=0;
}
void ms_rtp_recv_class_init(MSRtpRecvClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"RTPRecv");
MS_FILTER_CLASS(klass)->max_qoutputs=MSRTPRECV_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->max_foutputs=MSRTPRECV_MAX_OUTPUTS;
MS_FILTER_CLASS(klass)->w_maxgran=MSRTPRECV_DEF_GRAN;
ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE);
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_rtp_recv_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_rtp_recv_process;
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_rtp_recv_setup;
}
void ms_rtp_recv_process(MSRtpRecv *r)
{
MSFifo *fo;
MSQueue *qo;
MSSync *sync= r->sync;
void *d;
mblk_t *mp;
gint len;
gint gran=ms_sync_get_samples_per_tick(MS_SYNC(sync));
if (r->rtpsession==NULL) return;
/* process output fifo and output queue*/
fo=r->f_outputs[0];
if (fo!=NULL)
{
while( (mp=rtp_session_recvm_with_ts(r->rtpsession,r->prev_ts))!=NULL) {
/* try to get rtp packets and paste them to the output fifo */
r->stream_started=1;
len=mp->b_cont->b_wptr-mp->b_cont->b_rptr;
ms_fifo_get_write_ptr(fo,len,&d);
if (d!=NULL){
memcpy(d,mp->b_cont->b_rptr,len);
}else ms_warning("ms_rtp_recv_process: no space on output fifo !");
freemsg(mp);
}
r->prev_ts+=gran;
}
qo=r->q_outputs[0];
if (qo!=NULL)
{
guint32 clock;
gint got=0;
/* we are connected with queues (surely for video)*/
/* use the sync system time to compute a timestamp */
PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->send_pt);
if (pt==NULL) {
ms_warning("ms_rtp_recv_process(): NULL RtpPayload- skipping.");
return;
}
clock=(guint32)(((double)sync->time*(double)pt->clock_rate)/1000.0);
/*g_message("Querying packet with timestamp %u",clock);*/
/* get rtp packet, and send them through the output queue */
while ( (mp=rtp_session_recvm_with_ts(r->rtpsession,clock))!=NULL ){
MSMessage *msg;
mblk_t *mdata;
/*g_message("Got packet with timestamp %u",clock);*/
got++;
r->stream_started=1;
if (!r->ignore){
gboolean markbit=((rtp_header_t*)mp->b_rptr)->markbit;
mdata=mp->b_cont;
freeb(mp);
msg=msgb_2_ms_message(mdata);
msg->markbit=markbit;
ms_queue_put(qo,msg);
}else{
freemsg(mp);
}
}
}
}
void ms_rtp_recv_destroy( MSRtpRecv *obj)
{
g_free(obj);
}
static void __payload_type_changed(RtpSession *session,MSRtpRecv *obj){
int pt_num=rtp_session_get_recv_payload_type(session);
PayloadType *pt=rtp_profile_get_payload(rtp_session_get_profile(session),pt_num);
if (pt==NULL){
/* sip phone should ignore payload types they don't understand */
g_warning("Ignoring payload type %i",pt_num);
obj->ignore=TRUE;
}else{
if (obj->ignore) g_warning("payload type is coming back to something known");
obj->ignore=FALSE;
}
}
RtpSession * ms_rtp_recv_set_session(MSRtpRecv *obj,RtpSession *session)
{
RtpSession *old=obj->rtpsession;
obj->rtpsession=session;
rtp_session_signal_connect(session,"payload_type_changed",(RtpCallback)__payload_type_changed,(unsigned long)obj);
obj->prev_ts=0;
return old;
}
void ms_rtp_recv_setup(MSRtpRecv *r,MSSync *sync)
{
r->sync=sync;
r->stream_started=0;
}

View file

@ -1,82 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSRTPRECV_H
#define MSRTPRECV_H
#include "msfilter.h"
#include "mssync.h"
/* because of a conflict between config.h from oRTP and config.h from linphone:*/
#undef PACKAGE
#undef VERSION
#include <ortp/ortp.h>
/*this is the class that implements a copy filter*/
#define MSRTPRECV_MAX_OUTPUTS 1 /* max output per filter*/
#define MSRTPRECV_DEF_GRAN 320 /* the default granularity*/
struct _MSRtpRecv
{
/* the MSCopy derivates from MSFilter, so the MSFilter object MUST be the first of the MSCopy object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_outputs[MSRTPRECV_MAX_OUTPUTS];
MSQueue *q_outputs[MSRTPRECV_MAX_OUTPUTS];
MSSync *sync;
RtpSession *rtpsession;
guint32 prev_ts;
gint stream_started;
gint payload_expected;
gboolean ignore;
};
typedef struct _MSRtpRecv MSRtpRecv;
struct _MSRtpRecvClass
{
/* the MSCopy derivates from MSFilter, so the MSFilter class MUST be the first of the MSCopy class
in order to the class mechanism to work*/
MSFilterClass parent_class;
};
typedef struct _MSRtpRecvClass MSRtpRecvClass;
/* PUBLIC */
#define MS_RTP_RECV(filter) ((MSRtpRecv*)(filter))
#define MS_RTP_RECV_CLASS(klass) ((MSRtpRecvClass*)(klass))
MSFilter * ms_rtp_recv_new(void);
RtpSession * ms_rtp_recv_set_session(MSRtpRecv *obj,RtpSession *session);
#define ms_rtp_recv_unset_session(obj) (ms_rtp_recv_set_session((obj),NULL))
#define ms_rtp_recv_get_session(obj) ((obj)->rtpsession)
/* FOR INTERNAL USE*/
void ms_rtp_recv_init(MSRtpRecv *r);
void ms_rtp_recv_class_init(MSRtpRecvClass *klass);
void ms_rtp_recv_destroy( MSRtpRecv *obj);
void ms_rtp_recv_process(MSRtpRecv *r);
void ms_rtp_recv_setup(MSRtpRecv *r,MSSync *sync);
#endif

View file

@ -1,213 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msrtpsend.h"
#include <ortp/telephonyevents.h>
#include "mssync.h"
#include "mscodec.h"
static MSRtpSendClass *ms_rtp_send_class=NULL;
MSFilter * ms_rtp_send_new(void)
{
MSRtpSend *r;
r=g_new(MSRtpSend,1);
if (ms_rtp_send_class==NULL)
{
ms_rtp_send_class=g_new(MSRtpSendClass,1);
ms_rtp_send_class_init(ms_rtp_send_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_rtp_send_class);
ms_rtp_send_init(r);
return(MS_FILTER(r));
}
void ms_rtp_send_init(MSRtpSend *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos=r->f_inputs;
MS_FILTER(r)->inqueues=r->q_inputs;
MS_FILTER(r)->r_mingran=MSRTPSEND_DEF_GRAN;
memset(r->f_inputs,0,sizeof(MSFifo*)*MSRTPSEND_MAX_INPUTS);
memset(r->q_inputs,0,sizeof(MSFifo*)*MSRTPSEND_MAX_INPUTS);
r->rtpsession=NULL;
r->ts=0;
r->ts_inc=0;
r->flags=0;
r->delay=0;
}
void ms_rtp_send_class_init(MSRtpSendClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"RTPSend");
MS_FILTER_CLASS(klass)->max_qinputs=MSRTPSEND_MAX_INPUTS;
MS_FILTER_CLASS(klass)->max_finputs=MSRTPSEND_MAX_INPUTS;
MS_FILTER_CLASS(klass)->r_maxgran=MSRTPSEND_DEF_GRAN;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_rtp_send_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_rtp_send_process;
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_rtp_send_setup;
}
void ms_rtp_send_set_timing(MSRtpSend *r, guint32 ts_inc, gint payload_size)
{
r->ts_inc=ts_inc;
r->packet_size=payload_size;
if (r->ts_inc!=0) r->flags|=RTPSEND_CONFIGURED;
else r->flags&=~RTPSEND_CONFIGURED;
MS_FILTER(r)->r_mingran=payload_size;
/*g_message("ms_rtp_send_set_timing: ts_inc=%i",ts_inc);*/
}
guint32 get_new_timestamp(MSRtpSend *r,guint32 synctime)
{
guint32 clockts;
/* use the sync system time to compute a timestamp */
PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->send_pt);
g_return_val_if_fail(pt!=NULL,0);
clockts=(guint32)(((double)synctime * (double)pt->clock_rate)/1000.0);
ms_trace("ms_rtp_send_process: sync->time=%i clock=%i",synctime,clockts);
if (r->flags & RTPSEND_CONFIGURED){
if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(clockts,r->ts+(2*r->ts_inc) )){
r->ts=clockts;
}
else r->ts+=r->ts_inc;
}else{
r->ts=clockts;
}
return r->ts;
}
void ms_rtp_send_process(MSRtpSend *r)
{
MSFifo *fi;
MSQueue *qi;
MSSync *sync= r->sync;
int gran=ms_sync_get_samples_per_tick(sync);
guint32 ts;
void *s;
guint skip;
guint32 synctime=sync->time;
g_return_if_fail(gran>0);
if (r->rtpsession==NULL) return;
ms_filter_lock(MS_FILTER(r));
skip=r->delay!=0;
if (skip) r->delay--;
/* process output fifo and output queue*/
fi=r->f_inputs[0];
if (fi!=NULL)
{
ts=get_new_timestamp(r,synctime);
/* try to read r->packet_size bytes and send them in a rtp packet*/
ms_fifo_get_read_ptr(fi,r->packet_size,&s);
if (!skip){
rtp_session_send_with_ts(r->rtpsession,s,r->packet_size,ts);
ms_trace("len=%i, ts=%i ",r->packet_size,ts);
}
}
qi=r->q_inputs[0];
if (qi!=NULL)
{
MSMessage *msg;
/* read a MSMessage and send it through the network*/
while ( (msg=ms_queue_get(qi))!=NULL){
ts=get_new_timestamp(r,synctime);
if (!skip) {
/*g_message("Sending packet with ts=%u",ts);*/
mblk_t *packet=rtp_session_create_packet_with_data(r->rtpsession,msg->data,msg->size,NULL);
rtp_set_markbit(packet,msg->markbit);
rtp_session_sendm_with_ts(r->rtpsession,packet,ts);
}
ms_message_destroy(msg);
}
}
ms_filter_unlock(MS_FILTER(r));
}
void ms_rtp_send_destroy( MSRtpSend *obj)
{
g_free(obj);
}
RtpSession * ms_rtp_send_set_session(MSRtpSend *obj,RtpSession *session)
{
RtpSession *old=obj->rtpsession;
obj->rtpsession=session;
obj->ts=0;
obj->ts_inc=0;
return old;
}
void ms_rtp_send_setup(MSRtpSend *r, MSSync *sync)
{
MSFilter *codec;
MSCodecInfo *info;
r->sync=sync;
codec=ms_filter_search_upstream_by_type(MS_FILTER(r),MS_FILTER_AUDIO_CODEC);
if (codec==NULL) codec=ms_filter_search_upstream_by_type(MS_FILTER(r),MS_FILTER_VIDEO_CODEC);
if (codec==NULL){
g_warning("ms_rtp_send_setup: could not find upstream codec.");
return;
}
info=MS_CODEC_INFO(codec->klass->info);
if (info->info.type==MS_FILTER_AUDIO_CODEC){
int ts_inc=info->fr_size/2;
int psize=info->dt_size;
if (ts_inc==0){
/* dont'use the normal frame size: this is a variable frame size codec */
/* use the MS_FILTER(codec)->r_mingran */
ts_inc=MS_FILTER(codec)->r_mingran/2;
psize=0;
}
ms_rtp_send_set_timing(r,ts_inc,psize);
}
}
gint ms_rtp_send_dtmf(MSRtpSend *r, gchar dtmf)
{
gint res;
if (r->rtpsession==NULL) return -1;
if (rtp_session_telephone_events_supported(r->rtpsession)==-1){
g_warning("ERROR : telephone events not supported.\n");
return -1;
}
ms_filter_lock(MS_FILTER(r));
g_message("Sending DTMF.");
res=rtp_session_send_dtmf(r->rtpsession, dtmf, r->ts);
if (res==0){
//r->ts+=r->ts_inc;
r->delay+=2;
}else g_warning("Could not send dtmf.");
ms_filter_unlock(MS_FILTER(r));
return res;
}

View file

@ -1,85 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSRTPSEND_H
#define MSRTPSEND_H
#include "msfilter.h"
#include "mssync.h"
#undef PACKAGE
#undef VERSION
#include <ortp/ortp.h>
/*this is the class that implements a sending through rtp filter*/
#define MSRTPSEND_MAX_INPUTS 1 /* max input per filter*/
#define MSRTPSEND_DEF_GRAN 160/* the default granularity*/
struct _MSRtpSend
{
/* the MSCopy derivates from MSFilter, so the MSFilter object MUST be the first of the MSCopy object
in order to the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MSRTPSEND_MAX_INPUTS];
MSQueue *q_inputs[MSRTPSEND_MAX_INPUTS];
MSSync *sync;
RtpSession *rtpsession;
guint32 ts;
guint32 ts_inc; /* the timestamp increment */
gint packet_size;
guint flags;
guint delay; /* number of _proccess call which must be skipped */
#define RTPSEND_CONFIGURED (1)
};
typedef struct _MSRtpSend MSRtpSend;
struct _MSRtpSendClass
{
/* the MSRtpSend derivates from MSFilter, so the MSFilter class MUST be the first of the MSCopy class
in order to the class mechanism to work*/
MSFilterClass parent_class;
};
typedef struct _MSRtpSendClass MSRtpSendClass;
/* PUBLIC */
#define MS_RTP_SEND(filter) ((MSRtpSend*)(filter))
#define MS_RTP_SEND_CLASS(klass) ((MSRtpSendClass*)(klass))
MSFilter * ms_rtp_send_new(void);
RtpSession * ms_rtp_send_set_session(MSRtpSend *obj,RtpSession *session);
#define ms_rtp_send_unset_session(obj) (ms_rtp_send_set_session((obj),NULL))
#define ms_rtp_send_get_session(obj) ((obj)->rtpsession)
void ms_rtp_send_set_timing(MSRtpSend *r, guint32 ts_inc, gint payload_size);
gint ms_rtp_send_dtmf(MSRtpSend *r, gchar dtmf);
/* FOR INTERNAL USE*/
void ms_rtp_send_init(MSRtpSend *r);
void ms_rtp_send_class_init(MSRtpSendClass *klass);
void ms_rtp_send_destroy( MSRtpSend *obj);
void ms_rtp_send_process(MSRtpSend *r);
void ms_rtp_send_setup(MSRtpSend *r, MSSync *sync);
#endif

View file

@ -1,303 +0,0 @@
/***************************************************************************
* mssdlout.c
*
* Mon Jul 11 16:17:59 2005
* Copyright 2005 Simon Morlat
* Email simon dot morlat at linphone dot org
****************************************************************************/
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mssdlout.h"
MSSdlOutClass *ms_sdl_out_class=NULL;
void ms_sdl_out_init(MSSdlOut *obj){
ms_filter_init(MS_FILTER(obj));
obj->width=VIDEO_SIZE_CIF_W;
obj->height=VIDEO_SIZE_CIF_H;
obj->format="RGB24";
obj->use_yuv=FALSE;
obj->oldinm1=NULL;
MS_FILTER(obj)->inqueues=obj->input;
}
void ms_sdl_out_set_format(MSSdlOut *obj, const char *fmt){
obj->format=fmt;
if (strcmp(fmt,"YUV420P")==0) obj->use_yuv=TRUE;
else obj->use_yuv=FALSE;
}
void ms_sdl_uninit_sdl(MSSdlOut *obj){
if (obj->overlay!=NULL){
SDL_FreeYUVOverlay(obj->overlay);
obj->overlay=NULL;
}
if (obj->screen!=NULL){
SDL_FreeSurface(obj->screen);
obj->screen=NULL;
}
}
void ms_sdl_out_uninit(MSSdlOut *obj){
ms_sdl_uninit_sdl(obj);
}
void ms_sdl_out_destroy(MSSdlOut *obj){
ms_sdl_out_uninit(obj);
if (obj->oldinm1!=NULL) ms_message_destroy(obj->oldinm1);
g_free(obj);
}
void ms_sdl_init_sdl(MSSdlOut *obj){
if (strcmp(obj->format,"RGB24")==0){
}else{
obj->use_yuv=TRUE;
}
obj->screen = SDL_SetVideoMode(obj->width, obj->height, 0,SDL_HWSURFACE|SDL_ANYFORMAT);
if ( obj->screen == NULL ) {
g_warning("Couldn't set video mode: %s\n",
SDL_GetError());
return ;
}
if (obj->screen->flags & SDL_HWSURFACE) g_message("SDL surface created in hardware");
SDL_WM_SetCaption("Linphone Video", NULL);
if (obj->use_yuv){
g_message("Using yuv overlay.");
obj->overlay=SDL_CreateYUVOverlay(obj->width,obj->height,SDL_IYUV_OVERLAY,obj->screen);
if (obj->overlay==NULL){
g_warning("Couldn't create yuv overlay: %s\n",
SDL_GetError());
}else{
if (obj->overlay->hw_overlay) g_message("YUV overlay using hardware acceleration.");
}
}
}
static void resize_yuv_small(char *pict, int w, int h, int scale){
int i,j,id,jd;
int nh,nw;
char *smallpict;
int ysize,usize,ydsize,udsize;
int smallpict_sz;
char *dptr,*sptr;
nw=w/scale;
nh=h/scale;
ysize=w*h;
usize=ysize/4;
ydsize=nw*nh;
udsize=ydsize/4;
smallpict_sz=(ydsize*3)/2;
smallpict=(char*)alloca(smallpict_sz);
memset(smallpict,0,smallpict_sz);
dptr=smallpict;
sptr=pict;
for (j=0,jd=0;j<nh;j++,jd+=scale){
for (i=0,id=0;i<nw;i++,id+=scale){
dptr[(j*nw) + i]=sptr[(jd*w)+id];
}
}
nh=nh/2;
nw=nw/2;
w=w/2;
h=h/2;
dptr+=ydsize;
sptr+=ysize;
for (j=0,jd=0;j<nh;j++,jd+=scale){
for (i=0,id=0;i<nw;i++,id+=scale){
dptr[(j*nw) + i]=sptr[(jd*w)+id];
}
}
dptr+=udsize;
sptr+=usize;
for (j=0,jd=0;j<nh;j++,jd+=scale){
for (i=0,id=0;i<nw;i++,id+=scale){
dptr[(j*nw) + i]=sptr[(jd*w)+id];
}
}
memcpy(pict,smallpict,smallpict_sz);
}
static void fill_overlay_at_pos(SDL_Overlay *lay, MSMessage *m, int x, int y, int w, int h){
char *data=(char*)m->data;
int i,j;
int jlim,ilim;
int off;
char *dptr;
ilim=MIN(x+w,lay->w);
jlim=MIN(y+h,lay->h);
SDL_LockYUVOverlay(lay);
/* set Y */
dptr=lay->pixels[0];
for (j=y;j<jlim;j++){
off=j*lay->w;
for (i=x;i<ilim;i++){
dptr[off + i]=*data;
data++;
}
}
/*set U and V*/
ilim=ilim/2;
jlim=jlim/2;
dptr=lay->pixels[1];
for (j=y/2;j<jlim;j++){
off=j*(lay->w/2);
for (i=x/2;i<ilim;i++){
dptr[off + i]=*data;
data++;
}
}
dptr=lay->pixels[2];
for (j=y/2;j<jlim;j++){
off=j*(lay->w/2);
for (i=x/2;i<ilim;i++){
dptr[off + i]=*data;
data++;
}
}
SDL_UnlockYUVOverlay(lay);
}
static void fill_overlay(SDL_Overlay *lay, MSMessage *m){
int w2,h2;
char *data=(char*)m->data;
int ysize=lay->w*lay->h;
int usize;
w2=lay->w/2;
h2=lay->h/2;
usize=w2*h2;
SDL_LockYUVOverlay(lay);
memcpy(lay->pixels[0],data,ysize);
memcpy(lay->pixels[1],data+ysize,usize);
memcpy(lay->pixels[2],data+ysize+usize,usize);
SDL_UnlockYUVOverlay(lay);
}
#define SCALE_FACTOR 6
void ms_sdl_out_process(MSSdlOut *obj){
MSQueue *q0=obj->input[0];
MSQueue *q1=obj->input[1];
MSMessage *inm0=NULL;
MSMessage *inm1=NULL;
int err;
SDL_Rect smallrect;
SDL_Rect rect;
rect.w=obj->width;
rect.h=obj->height;
rect.x=0;
rect.y=0;
smallrect.w=obj->width/SCALE_FACTOR;
smallrect.h=obj->height/SCALE_FACTOR;
smallrect.x=obj->width - smallrect.w ;
smallrect.y=obj->height -smallrect.h;
if (obj->screen==NULL){
ms_sdl_init_sdl(obj);
}
if (q0!=NULL)
inm0=ms_queue_get(q0);
if (q1!=NULL)
inm1=ms_queue_get(q1);
if (inm0!=NULL){
SDL_Surface *surf;
if (obj->use_yuv){
fill_overlay(obj->overlay,inm0);
}else {
surf=SDL_CreateRGBSurfaceFrom(inm0->data,obj->width,obj->height,24,obj->width*3,0,0,0,0);
err=SDL_BlitSurface(surf,NULL,obj->screen,NULL);
if (err<0) g_warning("Fail to blit surface: %s",SDL_GetError());
SDL_FreeSurface(surf);
}
ms_message_destroy(inm0);
}
if (inm1!=NULL){
/* this message is blitted on the right,bottom corner of the screen */
SDL_Surface *surf;
if (obj->use_yuv){
resize_yuv_small(inm1->data,rect.w,rect.h,SCALE_FACTOR);
fill_overlay_at_pos(obj->overlay,inm1,smallrect.x, smallrect.y, smallrect.w, smallrect.h);
}else {
surf=SDL_CreateRGBSurfaceFrom(inm1->data,obj->width,obj->height,24,obj->width*3,0,0,0,0);
err=SDL_BlitSurface(surf,NULL,obj->screen,&smallrect);
if (err<0) g_warning("Fail to blit surface: %s",SDL_GetError());
SDL_FreeSurface(surf);
}
if (obj->oldinm1!=NULL) {
ms_message_destroy(obj->oldinm1);
}
obj->oldinm1=inm1;
}else{
/* this is the case were we have only inm0, we have to redisplay inm1 */
if (obj->use_yuv){
if (obj->oldinm1!=NULL){
fill_overlay_at_pos(obj->overlay,obj->oldinm1,smallrect.x, smallrect.y, smallrect.w, smallrect.h);
}
}
}
if (obj->use_yuv) SDL_DisplayYUVOverlay(obj->overlay,&rect);
SDL_UpdateRect(obj->screen,0,0,obj->width,obj->height);
}
void ms_sdl_out_class_init(MSSdlOutClass *klass){
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_sdl_out_process;
MS_FILTER_CLASS(klass)->max_qinputs=2;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_sdl_out_destroy;
MS_FILTER_CLASS(klass)->name="MSSdlOut";
/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
return;
}
/* Clean up on exit */
atexit(SDL_Quit);
}
MSFilter * ms_sdl_out_new(void){
MSSdlOut *obj=g_new0(MSSdlOut,1);
if (ms_sdl_out_class==NULL){
ms_sdl_out_class=g_new0(MSSdlOutClass,1);
ms_sdl_out_class_init(ms_sdl_out_class);
}
MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_sdl_out_class);
ms_sdl_out_init(obj);
return MS_FILTER(obj);
}

View file

@ -1,64 +0,0 @@
/***************************************************************************
* mssdlout.h
*
* Mon Jul 11 16:18:55 2005
* Copyright 2005 Simon Morlat
* Email simon dot morlat at linphone dot org
****************************************************************************/
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef mssdlout_h
#define mssdlout_h
#include "msfilter.h"
#include <SDL/SDL.h>
#include <SDL/SDL_video.h>
struct _MSSdlOut
{
MSFilter parent;
MSQueue *input[2];
gint width,height;
const gchar *format;
SDL_Surface *screen;
SDL_Overlay *overlay;
MSMessage *oldinm1;
gboolean use_yuv;
};
typedef struct _MSSdlOut MSSdlOut;
struct _MSSdlOutClass
{
MSFilterClass parent_class;
};
typedef struct _MSSdlOutClass MSSdlOutClass;
MSFilter * ms_sdl_out_new(void);
void ms_sdl_out_set_format(MSSdlOut *obj, const char *fmt);
#define MS_SDL_OUT(obj) ((MSSdlOut*)obj)
#endif

View file

@ -1,181 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mssmpeg.h"
#include <unistd.h>
#include <fcntl.h>
static MSSmpegClass *ms_smpeg_class=NULL;
int seek_mpeg_data(struct SDL_RWops *context, int offset, int whence)
{
MSSmpeg *obj=context->hidden.unknown.data1;
g_message("Entering seek function offset=%i whence=%i",offset,whence);
switch (whence)
{
case SEEK_SET:
obj->pos=offset;
break;
case SEEK_CUR:
return obj->pos;
break;
case SEEK_END:
return obj->end_pos;
break;
}
return 0;
}
int read_mpeg_data(struct SDL_RWops *context, void *ptr, int size, int maxnum)
{
MSSmpeg *obj=context->hidden.unknown.data1;
gint bytes;
g_message("Entering read function: size=%i maxnum=%i",size,maxnum);
if (obj->pos>=obj->end_pos)
{
g_message("End of file");
return 0;
}
if (obj->current==NULL)
{
g_message("Nothing to read.");
return 0;
}
bytes=MIN(maxnum,obj->current->size);
memcpy(ptr,obj->current->data,bytes);
obj->pos+=bytes;
//obj->current;
return bytes;
}
void ms_smpeg_init(MSSmpeg *obj)
{
gint error;
ms_filter_init(MS_FILTER(obj));
MS_FILTER(obj)->inqueues=obj->input;
obj->surface = SDL_SetVideoMode ( 400, 400,0 , SDL_HWSURFACE );
if (obj->surface==NULL)
{
g_error("Could not create a SDL surface");
}
/*
error=pipe(obj->fd);
if (error<0)
{
g_error("Could not create pipe !");
}
fcntl(obj->fd[1],F_SETFL,O_NONBLOCK);
*/
obj->rwops=SDL_AllocRW();
obj->rwops->read=read_mpeg_data;
obj->rwops->seek=seek_mpeg_data;
obj->rwops->hidden.unknown.data1=(void*)obj;
obj->pos=0;
obj->end_pos=0;
}
void ms_smpeg_class_init(MSSmpegClass *klass)
{
int error;
ms_filter_class_init(MS_FILTER_CLASS(klass));
MS_FILTER_CLASS(klass)->max_qinputs=1;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_smpeg_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_smpeg_process;
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MSSmpeg");
error=SDL_Init(SDL_INIT_VIDEO);
if (error<0){
g_error("Could not initialize SDL !");
}
}
void ms_smpeg_uninit(MSSmpeg *obj)
{
}
MSFilter * ms_smpeg_new()
{
MSSmpeg *obj=g_malloc(sizeof(MSSmpeg));
if (ms_smpeg_class==NULL)
{
ms_smpeg_class=g_malloc(sizeof(MSSmpegClass));
ms_smpeg_class_init(ms_smpeg_class);
}
MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_smpeg_class);
ms_smpeg_init(obj);
return MS_FILTER(obj);
}
void ms_smpeg_start(MSSmpeg *obj)
{
//SMPEG_play(obj->handle);
obj->first_time=1;
obj->run_cond=1;
}
void ms_smpeg_stop(MSSmpeg *obj)
{
SMPEG_stop(obj->handle);
obj->run_cond=0;
}
void ms_smpeg_process(MSSmpeg *obj)
{
MSQueue *q=obj->input[0];
MSMessage *m;
SMPEG_Info info;
while((m=ms_queue_get(q))!=NULL)
{
g_message("Getting new buffer");
if (obj->run_cond)
{
obj->current=m;
obj->end_pos+=m->size;
if (obj->first_time)
{
obj->handle=SMPEG_new_rwops(obj->rwops,NULL,0);
if (obj->handle==NULL){
g_error("Could not create smpeg object.");
}
SMPEG_setdisplay(obj->handle,obj->surface,NULL,NULL);
obj->first_time=0;
//SMPEG_play(obj->handle);
}
SMPEG_getinfo(obj->handle, &info );
g_message("Current frame is %i",info.current_frame);
SMPEG_renderFrame(obj->handle, info.current_frame+1);
}
ms_message_destroy(m);
obj->current=NULL;
}
}
void ms_smpeg_destroy(MSSmpeg *obj)
{
ms_smpeg_uninit(obj);
g_free(obj);
}

View file

@ -1,70 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSSMPEG_H
#define MSSMPEG_H
#include "ms.h"
#include "msfilter.h"
#include <smpeg/smpeg.h>
#include <SDL/SDL.h>
struct _MSSmpeg
{
MSFilter parent;
MSQueue *input[1];
SMPEG *handle;
SDL_Surface *surface;
SDL_RWops *rwops;
int run_cond;
int first_time;
MSMessage *current;
int pos;
int end_pos;
};
typedef struct _MSSmpeg MSSmpeg;
struct _MSSmpegClass
{
MSFilterClass parent_class;
};
typedef struct _MSSmpegClass MSSmpegClass;
#define MS_SMPEG(obj) ((MSSmpeg*)(obj))
#define MS_SMPEG_CLASS(klass) ((MSSmpegClass*)(klass))
void ms_smpeg_init(MSSmpeg *obj);
void ms_smpeg_class_init(MSSmpegClass *klass);
void ms_smpeg_uninit(MSSmpeg *obj);
MSFilter * ms_smpeg_new();
void ms_smpeg_start(MSSmpeg *obj);
void ms_smpeg_stop(MSSmpeg *obj);
void ms_smpeg_destroy(MSSmpeg *obj);
void ms_smpeg_process(MSSmpeg *obj);
#endif

View file

@ -1,38 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation
*/
#include "mssoundread.h"
void ms_sound_read_init(MSSoundRead *w)
{
ms_filter_init(MS_FILTER(w));
}
void ms_sound_read_class_init(MSSoundReadClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
MS_FILTER_CLASS(klass)->max_foutputs=1; /* one fifo output only */
ms_filter_class_set_attr( MS_FILTER_CLASS(klass),FILTER_IS_SOURCE);
}

View file

@ -1,80 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSSOUNDREAD_H
#define MSSOUNDREAD_H
#include "msfilter.h"
#include "mssync.h"
struct _MSSoundRead
{
/* the MSOssRead derivates from MSFilter, so the MSFilter object MUST be the first of the MSOssRead object
in order to the object mechanism to work*/
MSFilter filter;
};
typedef struct _MSSoundRead MSSoundRead;
struct _MSSoundReadClass
{
/* the MSOssRead derivates from MSFilter, so the MSFilter class MUST be the first of the MSOssRead class
in order to the class mechanism to work*/
MSFilterClass parent_class;
gint (*set_device)(MSSoundRead *, gint devid);
void (*start)(MSSoundRead *);
void (*stop)(MSSoundRead*);
void (*set_level)(MSSoundRead *, gint a);
};
typedef struct _MSSoundReadClass MSSoundReadClass;
/* PUBLIC */
#define MS_SOUND_READ(filter) ((MSSoundRead*)(filter))
#define MS_SOUND_READ_CLASS(klass) ((MSSoundReadClass*)(klass))
static inline int ms_sound_read_set_device(MSSoundRead *r,gint devid)
{
return MS_SOUND_READ_CLASS( MS_FILTER(r)->klass )->set_device(r,devid);
}
static inline void ms_sound_read_start(MSSoundRead *r)
{
MS_SOUND_READ_CLASS( MS_FILTER(r)->klass )->start(r);
}
static inline void ms_sound_read_stop(MSSoundRead *w)
{
MS_SOUND_READ_CLASS( MS_FILTER(w)->klass )->stop(w);
}
static inline void ms_sound_read_set_level(MSSoundRead *w,gint a)
{
MS_SOUND_READ_CLASS( MS_FILTER(w)->klass )->set_level(w,a);
}
/* FOR INTERNAL USE*/
void ms_sound_read_init(MSSoundRead *r);
void ms_sound_read_class_init(MSSoundReadClass *klass);
#endif

View file

@ -1,38 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation
*/
#include "mssoundwrite.h"
void ms_sound_write_init(MSSoundWrite *w)
{
ms_filter_init(MS_FILTER(w));
}
void ms_sound_write_class_init(MSSoundWriteClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
MS_FILTER_CLASS(klass)->max_finputs=1; /* one fifo output only */
ms_filter_class_set_attr( MS_FILTER_CLASS(klass),FILTER_IS_SINK);
}

View file

@ -1,80 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSSOUNDWRITE_H
#define MSSOUNDWRITE_H
#include "msfilter.h"
#include "mssync.h"
struct _MSSoundWrite
{
/* the MSOssWrite derivates from MSFilter, so the MSFilter object MUST be the first of the MSOssWrite object
in order to the object mechanism to work*/
MSFilter filter;
};
typedef struct _MSSoundWrite MSSoundWrite;
struct _MSSoundWriteClass
{
/* the MSOssWrite derivates from MSFilter, so the MSFilter class MUST be the first of the MSOssWrite class
in order to the class mechanism to work*/
MSFilterClass parent_class;
gint (*set_device)(MSSoundWrite *, gint devid);
void (*start)(MSSoundWrite *);
void (*stop)(MSSoundWrite*);
void (*set_level)(MSSoundWrite *, gint a);
};
typedef struct _MSSoundWriteClass MSSoundWriteClass;
/* PUBLIC */
#define MS_SOUND_WRITE(filter) ((MSSoundWrite*)(filter))
#define MS_SOUND_WRITE_CLASS(klass) ((MSSoundWriteClass*)(klass))
static inline int ms_sound_write_set_device(MSSoundWrite *r,gint devid)
{
return MS_SOUND_WRITE_CLASS( MS_FILTER(r)->klass )->set_device(r,devid);
}
static inline void ms_sound_write_start(MSSoundWrite *r)
{
MS_SOUND_WRITE_CLASS( MS_FILTER(r)->klass )->start(r);
}
static inline void ms_sound_write_stop(MSSoundWrite *w)
{
MS_SOUND_WRITE_CLASS( MS_FILTER(w)->klass )->stop(w);
}
static inline void ms_sound_write_set_level(MSSoundWrite *w,gint a)
{
MS_SOUND_WRITE_CLASS( MS_FILTER(w)->klass )->set_level(w,a);
}
/* FOR INTERNAL USE*/
void ms_sound_write_init(MSSoundWrite *r);
void ms_sound_write_class_init(MSSoundWriteClass *klass);
#endif

View file

@ -1,215 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msspeexdec.h"
#ifdef HAVE_GLIB
#include <gmodule.h>
#endif
extern MSFilter * ms_speex_enc_new();
MSCodecInfo speex_info=
{
{
"Speex codec",
0,
MS_FILTER_AUDIO_CODEC,
ms_speex_dec_new,
"A high quality variable bit-rate codec from Jean Marc Valin and David Rowe."
},
ms_speex_enc_new,
ms_speex_dec_new,
0, /*frame size */
0,
8000, /*minimal bitrate */
-1, /* sampling frequency */
110, /* payload type */
"speex",
1,
1
};
void ms_speex_codec_init()
{
ms_filter_register(MS_FILTER_INFO(&speex_info));
//ms_filter_register(MS_FILTER_INFO(&speex_lbr_info));
}
#ifdef HAVE_GLIB
gchar * g_module_check_init(GModule *module)
{
ms_speex_codec_init();
return NULL;
}
#else
gchar * g_module_check_init()
{
ms_speex_codec_init();
return NULL;
}
#endif
static MSSpeexDecClass * ms_speex_dec_class=NULL;
//static MSSpeexDecClass * ms_speexnb_dec_class=NULL;
MSFilter * ms_speex_dec_new()
{
MSSpeexDec *obj=g_new(MSSpeexDec,1);
if (ms_speex_dec_class==NULL){
ms_speex_dec_class=g_new(MSSpeexDecClass,1);
ms_speex_dec_class_init(ms_speex_dec_class);
}
MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_speex_dec_class);
ms_speex_dec_init(obj);
return MS_FILTER(obj);
}
void ms_speex_dec_init(MSSpeexDec *obj)
{
ms_filter_init(MS_FILTER(obj));
obj->initialized=0;
MS_FILTER(obj)->outfifos=obj->outf;
MS_FILTER(obj)->inqueues=obj->inq;
obj->outf[0]=NULL;
obj->inq[0]=NULL;
obj->frequency=8000; /*default value */
}
void ms_speex_dec_init_core(MSSpeexDec *obj,const SpeexMode *mode)
{
int pf=1;
obj->speex_state=speex_decoder_init((SpeexMode*)mode);
speex_bits_init(&obj->bits);
/* enable the perceptual post filter */
speex_decoder_ctl(obj->speex_state,SPEEX_SET_PF, &pf);
speex_mode_query((SpeexMode*)mode, SPEEX_MODE_FRAME_SIZE, &obj->frame_size);
obj->initialized=1;
}
int ms_speex_dec_set_property(MSSpeexDec *obj, MSFilterProperty prop, int *value)
{
if (obj->initialized){
/* we are called when speex is running !! forbid that! */
ms_warning("ms_speex_dec_set_property: cannot call this function when running!");
return -1;
}
switch(prop){
case MS_FILTER_PROPERTY_FREQ:
obj->frequency=value[0];
break;
default:
break;
}
return 0;
}
void ms_speex_dec_setup(MSSpeexDec *obj)
{
const SpeexMode *mode;
g_message("Speex decoder setup: freq=%i",obj->frequency);
if ( obj->frequency< 16000) mode=&speex_nb_mode;
else mode=&speex_wb_mode;
ms_speex_dec_init_core(obj,mode);
}
void ms_speex_dec_unsetup(MSSpeexDec *obj)
{
ms_speex_dec_uninit_core(obj);
}
void ms_speex_dec_class_init(MSSpeexDecClass *klass)
{
gint frame_size=0;
ms_filter_class_init(MS_FILTER_CLASS(klass));
/* use the largest frame size to configure fifos */
speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size);
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_dec_process;
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_dec_setup;
MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_dec_unsetup;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_dec_destroy;
MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_dec_set_property;
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexDecoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info;
MS_FILTER_CLASS(klass)->max_foutputs=1;
MS_FILTER_CLASS(klass)->max_qinputs=1;
MS_FILTER_CLASS(klass)->w_maxgran=frame_size*2;
ms_trace("ms_speex_dec_class_init: w_maxgran is %i.",MS_FILTER_CLASS(klass)->w_maxgran);
}
void ms_speex_dec_uninit_core(MSSpeexDec *obj)
{
speex_decoder_destroy(obj->speex_state);
speex_bits_destroy(&obj->bits);
obj->initialized=0;
}
void ms_speex_dec_uninit(MSSpeexDec *obj)
{
}
void ms_speex_dec_destroy(MSSpeexDec *obj)
{
ms_speex_dec_uninit(obj);
g_free(obj);
}
void ms_speex_dec_process(MSSpeexDec *obj)
{
MSFifo *outf=obj->outf[0];
MSQueue *inq=obj->inq[0];
gint16 *output;
gint gran=obj->frame_size*2;
MSMessage *m;
g_return_if_fail(inq!=NULL);
g_return_if_fail(outf!=NULL);
m=ms_queue_get(inq);
g_return_if_fail(m!=NULL);
speex_bits_reset(&obj->bits);
ms_fifo_get_write_ptr(outf,gran,(void**)&output);
g_return_if_fail(output!=NULL);
if (m->data!=NULL){
speex_bits_read_from(&obj->bits,m->data,m->size);
/* decode */
speex_decode_int(obj->speex_state,&obj->bits,(short*)output);
}else{
/* we have a missing packet */
speex_decode_int(obj->speex_state,NULL,(short*)output);
}
ms_message_destroy(m);
}

View file

@ -1,69 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSSPEEXDEC_H
#define MSSPEEXDEC_H
#include "mscodec.h"
#include <speex/speex.h>
struct _MSSpeexDec
{
MSFilter parent;
MSQueue *inq[1]; /* speex has an input q because it can be variable bit rate */
MSFifo *outf[1];
void *speex_state;
SpeexBits bits;
int frequency;
int frame_size;
int initialized;
};
typedef struct _MSSpeexDec MSSpeexDec;
struct _MSSpeexDecClass
{
MSFilterClass parent;
};
typedef struct _MSSpeexDecClass MSSpeexDecClass;
#define MS_SPEEX_DEC(o) ((MSSpeexDec*)(o))
#define MS_SPEEX_DEC_CLASS(o) ((MSSpeexDecClass*)(o))
/* call this before if don't load the plugin dynamically */
void ms_speex_codec_init();
/* mediastreamer compliant constructor */
MSFilter * ms_speex_dec_new();
void ms_speex_dec_init(MSSpeexDec *obj);
void ms_speex_dec_init_core(MSSpeexDec *obj,const SpeexMode *mode);
void ms_speex_dec_class_init(MSSpeexDecClass *klass);
void ms_speex_dec_uninit(MSSpeexDec *obj);
void ms_speex_dec_uninit_core(MSSpeexDec *obj);
void ms_speex_dec_process(MSSpeexDec *obj);
void ms_speex_dec_destroy(MSSpeexDec *obj);
#endif

View file

@ -1,187 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "msspeexenc.h"
#include "ms.h"
extern MSCodecInfo speex_info;
static MSSpeexEncClass * ms_speex_enc_class=NULL;
MSFilter * ms_speex_enc_new()
{
MSSpeexEnc *obj=g_new(MSSpeexEnc,1);
if (ms_speex_enc_class==NULL){
ms_speex_enc_class=g_new(MSSpeexEncClass,1);
ms_speex_enc_class_init(ms_speex_enc_class);
}
MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_speex_enc_class);
ms_speex_enc_init(MS_SPEEX_ENC(obj));
return MS_FILTER(obj);
}
void ms_speex_enc_init(MSSpeexEnc *obj)
{
ms_filter_init(MS_FILTER(obj));
MS_FILTER(obj)->infifos=obj->inf;
MS_FILTER(obj)->outqueues=obj->outq;
obj->inf[0]=NULL;
obj->outq[0]=NULL;
obj->frequency=8000;
obj->bitrate=30000;
obj->initialized=0;
}
void ms_speex_enc_init_core(MSSpeexEnc *obj,const SpeexMode *mode, gint bitrate)
{
int proc_type, proc_speed;
gchar *proc_vendor;
int tmp;
int frame_size;
obj->speex_state=speex_encoder_init((SpeexMode*)mode);
speex_bits_init(&obj->bits);
if (bitrate>0) {
bitrate++;
speex_encoder_ctl(obj->speex_state, SPEEX_SET_BITRATE, &bitrate);
g_message("Setting speex output bitrate less or equal than %i",bitrate-1);
}
proc_speed=ms_proc_get_speed();
proc_vendor=ms_proc_get_param("vendor_id");
if (proc_speed<0 || proc_vendor==NULL){
g_warning("Can't guess processor features: setting speex encoder to its lowest complexity.");
tmp=1;
speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp);
}else if ((proc_speed!=-1) && (proc_speed<200)){
g_warning("A cpu speed less than 200 Mhz is not enough: let's reduce the complexity of the speex codec.");
tmp=1;
speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp);
}else if (proc_vendor!=NULL) {
if (strncmp(proc_vendor,"GenuineIntel",strlen("GenuineIntel"))==0){
proc_type=ms_proc_get_type();
if (proc_type==5){
g_warning("A pentium I is not enough fast for speex codec in normal mode: let's reduce its complexity.");
tmp=1;
speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp);
}
}
g_free(proc_vendor);
}
/* guess the used input frame size */
speex_mode_query((SpeexMode*)mode, SPEEX_MODE_FRAME_SIZE, &frame_size);
MS_FILTER(obj)->r_mingran=frame_size*2;
ms_trace("ms_speex_init: using frame size of %i.",MS_FILTER(obj)->r_mingran);
obj->initialized=1;
}
/* must be called before the encoder is running*/
int ms_speex_enc_set_property(MSSpeexEnc *obj,int property,int *value)
{
if (obj->initialized){
/* we are called when speex is running !! forbid that! */
ms_warning("ms_speex_enc_set_property: cannot call this function when running!");
return -1;
}
switch(property){
case MS_FILTER_PROPERTY_FREQ:
obj->frequency=value[0];
break;
case MS_FILTER_PROPERTY_BITRATE: /* to specify max bitrate */
obj->bitrate=value[0];
break;
}
return 0;
}
void ms_speex_enc_setup(MSSpeexEnc *obj)
{
const SpeexMode *mode;
g_message("Speex encoder setup: freq=%i",obj->frequency);
if ( obj->frequency< 16000) mode=&speex_nb_mode;
else mode=&speex_wb_mode;
ms_speex_enc_init_core(obj,mode,obj->bitrate);
}
void ms_speex_enc_unsetup(MSSpeexEnc *obj)
{
ms_speex_enc_uninit_core(obj);
}
void ms_speex_enc_class_init(MSSpeexEncClass *klass)
{
gint frame_size=0;
ms_filter_class_init(MS_FILTER_CLASS(klass));
/* we take the larger (wb) frame size */
speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size);
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_enc_process;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_enc_destroy;
MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_enc_setup;
MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_enc_unsetup;
MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_enc_set_property;
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexEncoder");
MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info;
MS_FILTER_CLASS(klass)->max_finputs=1;
MS_FILTER_CLASS(klass)->max_qoutputs=1;
MS_FILTER_CLASS(klass)->r_maxgran=frame_size*2;
ms_trace("ms_speex_enc_class_init: r_maxgran is %i.",MS_FILTER_CLASS(klass)->r_maxgran);
}
void ms_speex_enc_uninit_core(MSSpeexEnc *obj)
{
if (obj->initialized){
speex_encoder_destroy(obj->speex_state);
speex_bits_destroy(&obj->bits);
obj->initialized=0;
}
}
void ms_speex_enc_destroy(MSSpeexEnc *obj)
{
ms_speex_enc_uninit_core(obj);
g_free(obj);
}
void ms_speex_enc_process(MSSpeexEnc *obj)
{
MSFifo *inf=obj->inf[0];
MSQueue *outq=obj->outq[0];
gint16 *input;
gint gran=MS_FILTER(obj)->r_mingran;
MSMessage *m;
g_return_if_fail(inf!=NULL);
g_return_if_fail(outq!=NULL);
ms_fifo_get_read_ptr(inf,gran,(void**)&input);
g_return_if_fail(input!=NULL);
/* encode */
speex_bits_reset(&obj->bits);
speex_encode_int(obj->speex_state,(short*)input,&obj->bits);
m=ms_message_new(speex_bits_nbytes(&obj->bits));
m->size=speex_bits_write(&obj->bits,m->data,m->size);
ms_queue_put(outq,m);
}

View file

@ -1,66 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSSPEEXENC_H
#define MSSPEEXENC_H
#include "mscodec.h"
#include <speex/speex.h>
struct _MSSpeexEnc
{
MSFilter parent;
MSFifo *inf[1];
MSQueue *outq[1]; /* speex has an output q because it can be variable bit rate */
void *speex_state;
SpeexBits bits;
int frequency;
int bitrate;
int initialized;
};
typedef struct _MSSpeexEnc MSSpeexEnc;
struct _MSSpeexEncClass
{
MSFilterClass parent;
};
typedef struct _MSSpeexEncClass MSSpeexEncClass;
#define MS_SPEEX_ENC(o) ((MSSpeexEnc*)(o))
#define MS_SPEEX_ENC_CLASS(o) ((MSSpeexEncClass*)(o))
/* generic constructor */
MSFilter * ms_speex_enc_new();
void ms_speex_enc_init_core(MSSpeexEnc *obj,const SpeexMode *mode, gint quality);
void ms_speex_enc_uninit_core(MSSpeexEnc *obj);
void ms_speex_enc_init(MSSpeexEnc *obj);
void ms_speex_enc_class_init(MSSpeexEncClass *klass);
void ms_speex_enc_process(MSSpeexEnc *obj);
void ms_speex_enc_destroy(MSSpeexEnc *obj);
#endif

View file

@ -1,194 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mssync.h"
#include <errno.h>
/* TODO:
-define an uninit function that free the mutex
*/
/**
* function_name:ms_sync_get_bytes_per_tick
* @sync: A #MSSync object.
*
* Returns the number of bytes per tick. This is a usefull information for sources, so
* that they can know how much data they must deliver each time they are called.
*
*/
/* private */
void ms_sync_init(MSSync *sync)
{
sync->klass=NULL;
sync->lock=g_mutex_new();
sync->thread_cond=g_cond_new();
sync->stop_cond=g_cond_new();
sync->attached_filters=NULL;
sync->execution_list=NULL;
sync->filters=0;
sync->run=0;
sync->flags=0;
sync->samples_per_tick=0;
sync->ticks=0;
sync->time=0;
sync->thread=NULL;
}
void ms_sync_class_init(MSSyncClass *klass)
{
klass->max_filters=0;
klass->synchronize=NULL;
klass->attach=ms_sync_attach_generic;
klass->detach=ms_sync_detach_generic;
klass->destroy=NULL;
}
/* public*/
/**
* ms_sync_attach:
* @sync: A #MSSync object.
* @f: A #MSFilter object.
*
* Attach a chain of filters to a synchronisation source @sync. Filter @f must be the first filter of the processing chain.
* In order to be run, each chain of filter must be attached to a synchronisation source, that will be responsible for scheduling
* the processing. Multiple chains can be attached to a single synchronisation.
*
* Returns: 0 if successfull, a negative value reprensenting the errno.h error.
*/
int ms_sync_attach(MSSync *sync,MSFilter *f)
{
gint err;
ms_sync_lock(sync);
err=sync->klass->attach(sync,f);
ms_sync_update(sync);
ms_sync_unlock(sync);
return(err);
}
int ms_sync_attach_generic(MSSync *sync,MSFilter *f)
{
int i;
//printf("attr: %i\n",f->klass->attributes);
g_return_val_if_fail(f->klass->attributes & FILTER_IS_SOURCE,-EINVAL);
g_return_val_if_fail(sync->attached_filters!=NULL,-EFAULT);
/* find a free place to attach*/
for (i=0;i<sync->klass->max_filters;i++)
{
if (sync->attached_filters[i]==NULL)
{
sync->attached_filters[i]=f;
sync->filters++;
ms_trace("Filter succesfully attached to sync.");
return 0;
}
}
g_warning("No more link on sync !");
return(-EMLINK);
}
/**
* ms_sync_detach:
* @sync: A #MSSync object.
* @f: A #MSFilter object.
*
* Dettach a chain of filters to a synchronisation source. Filter @f must be the first filter of the processing chain.
* The processing chain will no more be executed.
*
* Returns: 0 if successfull, a negative value reprensenting the errno.h error.
*/
int ms_sync_detach(MSSync *sync,MSFilter *f)
{
gint err;
ms_sync_lock(sync);
err=sync->klass->detach(sync,f);
ms_sync_update(sync);
ms_sync_unlock(sync);
return(err);
}
int ms_sync_detach_generic(MSSync *sync,MSFilter *f)
{
int i;
g_return_val_if_fail(f->klass->attributes & FILTER_IS_SOURCE,-EINVAL);
g_return_val_if_fail(sync->attached_filters!=NULL,-EFAULT);
for (i=0;i<sync->filters;i++)
{
if (sync->attached_filters[i]==f)
{
sync->attached_filters[i]=NULL;
sync->filters--;
return 0;
}
}
return(-EMLINK);
}
void ms_sync_set_samples_per_tick(MSSync *sync,gint size)
{
if (sync->samples_per_tick==0)
{
sync->samples_per_tick=size;
g_cond_signal(sync->thread_cond);
}
else sync->samples_per_tick=size;
}
/* call the setup func of each filter attached to the graph */
void ms_sync_setup(MSSync *sync)
{
GList *elem=sync->execution_list;
MSFilter *f;
while(elem!=NULL){
f=(MSFilter*)elem->data;
if (f->klass->setup!=NULL){
f->klass->setup(f,sync);
}
elem=g_list_next(elem);
}
}
/* call the unsetup func of each filter attached to the graph */
void ms_sync_unsetup(MSSync *sync)
{
GList *elem=sync->execution_list;
MSFilter *f;
while(elem!=NULL){
f=(MSFilter*)elem->data;
if (f->klass->unsetup!=NULL){
f->klass->unsetup(f,sync);
}
elem=g_list_next(elem);
}
}
int ms_sync_uninit(MSSync *sync)
{
g_mutex_free(sync->lock);
g_cond_free(sync->thread_cond);
g_cond_free(sync->stop_cond);
return 0;
}

View file

@ -1,136 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MS_SYNC_H
#define MS_SYNC_H
#include "msfilter.h"
struct _MSSync
{
struct _MSSyncClass *klass;
GMutex *lock;
MSFilter **attached_filters; /* pointer to a table of pointer of filters*/
GList *execution_list; /* the list of filters to be executed. This is filled with compilation */
gint filters; /*number of filters attached to the sync */
gint run; /* flag to indicate whether the sync must be run or not */
GThread * thread; /* the thread ressource if this sync is run by a thread*/
GCond *thread_cond;
GCond *stop_cond;
guint32 flags;
gint interval; /* in miliseconds*/
#define MS_SYNC_NEED_UPDATE (0x0001) /* a modification has occured in the processing chains
attached to this sync; so the execution list has to be updated */
guint samples_per_tick; /* number of bytes produced by sources of the processing chains*/
guint32 ticks;
guint32 time; /* a time since the start of the sync expressed in milisec*/
};
typedef struct _MSSync MSSync;
typedef void (*MSSyncDestroyFunc)(MSSync*);
typedef void (*MSSyncSyncFunc)(MSSync*);
typedef int (*MSSyncAttachFunc)(MSSync*,MSFilter*);
typedef int (*MSSyncDetachFunc)(MSSync*,MSFilter*);
typedef struct _MSSyncClass
{
gint max_filters; /* the maximum number of filters that can be attached to this sync*/
MSSyncSyncFunc synchronize;
MSSyncDestroyFunc destroy;
MSSyncAttachFunc attach;
MSSyncDetachFunc detach;
} MSSyncClass;
/* private */
void ms_sync_init(MSSync *sync);
void ms_sync_class_init(MSSyncClass *klass);
int ms_sync_attach_generic(MSSync *sync,MSFilter *f);
int ms_sync_detach_generic(MSSync *sync,MSFilter *f);
/* public*/
#define MS_SYNC(sync) ((MSSync*)(sync))
#define MS_SYNC_CLASS(klass) ((MSSyncClass*)(klass))
#define ms_sync_synchronize(_sync) \
do \
{ \
MSSync *__sync=_sync; \
__sync->ticks++; \
((__sync)->klass->synchronize((__sync))); \
}while(0)
void ms_sync_setup(MSSync *sync);
void ms_sync_unsetup(MSSync *sync);
#define ms_sync_update(sync) (sync)->flags|=MS_SYNC_NEED_UPDATE
#define ms_sync_get_samples_per_tick(sync) ((sync)->samples_per_tick)
void ms_sync_set_samples_per_tick(MSSync *sync,gint size);
#define ms_sync_get_tick_count(sync) ((sync)->ticks)
#define ms_sync_suspend(sync) g_cond_wait((sync)->thread_cond,(sync)->lock)
#define ms_sync_lock(sync) g_mutex_lock((sync)->lock)
#define ms_sync_unlock(sync) g_mutex_unlock((sync)->lock)
#define ms_sync_trylock(sync) g_mutex_trylock((sync)->lock)
/**
* function_name:ms_sync_attach
* @sync: A #MSSync object.
* @f: A #MSFilter object.
*
* Attach a chain of filters to a synchronisation source. Filter @f must be the first filter of the processing chain.
*
* Returns: 0 if successfull, a negative value reprensenting the errno.h error.
*/
int ms_sync_attach(MSSync *sync,MSFilter *f);
/**
* ms_sync_detach:
* @sync: A #MSSync object.
* @f: A #MSFilter object.
*
* Dettach a chain of filters to a synchronisation source. Filter @f must be the first filter of the processing chain.
* The processing chain will no more be executed.
*
* Returns: 0 if successfull, a negative value reprensenting the errno.h error.
*/
int ms_sync_detach(MSSync *sync,MSFilter *f);
int ms_sync_uninit(MSSync *sync);
#define ms_sync_start(sync) ms_start((sync))
#define ms_sync_stop(sync) ms_stop((sync))
/*destroy*/
#define ms_sync_destroy(sync) (sync)->klass->destroy((sync))
#endif

View file

@ -1,137 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mstcpclient.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
void ms_tcp_client_process(MSTcpClient *r);
void ms_tcp_client_init(MSTcpClient *r);
void ms_tcp_client_destroy(MSTcpClient *r);
void ms_tcp_client_class_init(MSTcpClientClass *klass);
static MSTcpClientClass *ms_tcp_client_class=NULL;
MSFilter * ms_tcp_client_new(void)
{
MSTcpClient *r;
r=g_new(MSTcpClient,1);
if (ms_tcp_client_class==NULL)
{
ms_tcp_client_class=g_new(MSTcpClientClass,1);
ms_tcp_client_class_init(ms_tcp_client_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_tcp_client_class);
ms_tcp_client_init(r);
return(MS_FILTER(r));
}
void ms_tcp_client_init(MSTcpClient *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->outqueues=r->q_outputs;
memset(r->q_outputs,0,sizeof(MSQueue*));
r->sock=-1;
r->msg=NULL;
}
int ms_tcp_client_connect(MSTcpClient *obj, const char *addr, int port){
struct addrinfo hints;
struct addrinfo *res;
char service[40];
int err;
sprintf(service,"%i",port);
memset(&hints,0,sizeof(hints));
hints.ai_family=PF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
err=getaddrinfo(addr,service,&hints,&res);
if (err!=0){
g_warning("getaddrinfo error: %s",gai_strerror(err));
return -1;
}
obj->sock=socket(res->ai_family,res->ai_socktype,0);
if (obj->sock<0){
g_warning("fail to create socket: %s",strerror(errno));
return -1;
}
err=connect(obj->sock,res->ai_addr,res->ai_addrlen);
if (err<0){
g_warning("Could not connect to %s:%i : %s",addr,port,strerror(errno));
close(obj->sock);
obj->sock=-1;
return -1;
}
return 0;
}
void ms_tcp_client_class_init(MSTcpClientClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"TcpClient");
MS_FILTER_CLASS(klass)->max_qoutputs=1;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_tcp_client_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_tcp_client_process;
ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE);
}
void ms_tcp_client_process(MSTcpClient *r)
{
static const int rcvsz=5000;
int err;
if (r->sock>0){
if (r->msg==NULL){
r->msg=ms_message_new(rcvsz);
memset(r->msg->data,0,rcvsz);
}
err=recv(r->sock,r->msg->data,rcvsz,MSG_DONTWAIT);
if (err<0 && errno!=EWOULDBLOCK && errno!=EAGAIN){
g_warning("recv error: %s",strerror(errno));
}else if (err>0){
r->msg->size=err;
ms_queue_put(r->q_outputs[0],r->msg);
printf("output new message %p,%i\n",r->msg->data,r->msg->size);
r->msg=NULL;
}
}
}
void ms_tcp_client_uninit( MSTcpClient *obj){
if (obj->sock>0) close(obj->sock);
if (obj->msg!=NULL) ms_message_destroy(obj->msg);
}
void ms_tcp_client_destroy( MSTcpClient *obj)
{
ms_tcp_client_uninit(obj);
g_free(obj);
}

View file

@ -1,50 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef mstcpclient_h
#define mstcpclient_h
#include "msfilter.h"
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
struct _MSTcpClient{
MSFilter parent;
MSQueue *q_outputs[1];
int sock;
MSMessage *msg;
};
typedef struct _MSTcpClient MSTcpClient;
struct _MSTcpClientClass{
MSFilterClass parent;
};
typedef struct _MSTcpClientClass MSTcpClientClass;
MSFilter *ms_tcp_client_new();
int ms_tcp_client_connect(MSTcpClient *obj, const char *addr, int port);
#define MS_TCP_CLIENT(o) ((MSTcpClient*)(o))
#endif

View file

@ -1,174 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mstcpserv.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
void ms_tcp_serv_process(MSTcpServ *r);
void ms_tcp_serv_init(MSTcpServ *r, int port);
void ms_tcp_serv_destroy(MSTcpServ *r);
void ms_tcp_serv_class_init(MSTcpServClass *klass);
static MSTcpServClass *ms_tcp_serv_class=NULL;
MSFilter * ms_tcp_serv_new(void)
{
MSTcpServ *r;
r=g_new(MSTcpServ,1);
if (ms_tcp_serv_class==NULL)
{
ms_tcp_serv_class=g_new(MSTcpServClass,1);
ms_tcp_serv_class_init(ms_tcp_serv_class);
}
MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_tcp_serv_class);
ms_tcp_serv_init(r,5800);
return(MS_FILTER(r));
}
void ms_tcp_serv_init(MSTcpServ *r, int port)
{
struct addrinfo *res;
struct addrinfo hints;
char service[20];
int err;
int val=1;
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->inqueues=r->q_inputs;
memset(r->q_inputs,0,sizeof(MSQueue*));
memset(&r->set,0,sizeof(fd_set));
r->maxfd=0;
r->asock=socket(PF_INET,SOCK_STREAM,0);
if (r->asock<0){
g_warning("Could not create socket: %s",strerror(errno));
return;
}
err=fcntl(r->asock,F_SETFL,O_NONBLOCK);
if (err<0){
g_warning("Could not non blocking flag on socket: %s",strerror(errno));
return;
}
err=setsockopt(r->asock,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(int));
if (err<0){
g_warning("Could not set socket reusable: %s",strerror(errno));
return;
}
sprintf(service,"%i",port);
memset(&hints,0,sizeof(hints));
hints.ai_family=PF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
if (err=getaddrinfo("0.0.0.0",service,&hints,&res)!=0){
g_warning("Could not getaddrinfo: %s",gai_strerror(err));
return;
}
err=bind(r->asock,(struct sockaddr *)res->ai_addr,res->ai_addrlen);
freeaddrinfo(res);
if (err<0){
g_warning("Could not bind socket: %s",strerror(errno));
return;
}
err=listen(r->asock,10);
if (err<0){
g_warning("Could not listen: %s",strerror(errno));
return;
}
}
void ms_tcp_serv_class_init(MSTcpServClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass),"TcpServ");
MS_FILTER_CLASS(klass)->max_qinputs=1;
MS_FILTER_CLASS(klass)->max_finputs=0;
MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_tcp_serv_destroy;
MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_tcp_serv_process;
}
static void accept_new_clients(MSTcpServ *r){
int sock;
struct sockaddr_storage ss;
socklen_t len=sizeof(ss);
int val=1;
int err;
sock=accept(r->asock,(struct sockaddr*)&ss,&len);
if (sock<0){
if (errno!=EWOULDBLOCK && errno!=EAGAIN) g_warning("Could not accept connection: %s",strerror(errno));
return;
}
FD_SET(sock,&r->set);
err=setsockopt(sock,SOL_TCP,TCP_NODELAY,&val,sizeof(int));
if (err<0){
g_warning("Could not set tcp nodelay option: %s",strerror(errno));
}
if (r->maxfd<sock) r->maxfd=sock;
printf("New client accepted.\n");
}
void ms_tcp_serv_process(MSTcpServ *r)
{
MSMessage *msg;
int err;
g_return_if_fail(r->asock>0);
/*printf("ms_tcp_serv_process\n");*/
/* first accept incoming connections */
accept_new_clients(r);
/* send data to all clients */
msg=ms_queue_get(r->q_inputs[0]);
if (msg!=NULL){
int i;
for (i=0;i<r->maxfd+1;i++){
if (FD_ISSET(i,&r->set)){
err=send(i,msg->data,msg->size,0);
if (err<0){
FD_CLR(i,&r->set);
close(i);
g_message("Client disconnected.");
}
}
}
ms_message_destroy(msg);
}
}
void ms_tcp_serv_uninit( MSTcpServ *obj){
if (obj->asock>0) close(obj->asock);
}
void ms_tcp_serv_destroy( MSTcpServ *obj)
{
ms_tcp_serv_uninit(obj);
g_free(obj);
}

View file

@ -1,33 +0,0 @@
#ifndef mstcpserver_h
#define mstcpserver_h
#include "msfilter.h"
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
struct _MSTcpServ{
MSFilter parent;
MSQueue *q_inputs[1];
fd_set set;
int maxfd;
int asock;
};
typedef struct _MSTcpServ MSTcpServ;
struct _MSTcpServClass{
MSFilterClass parent;
};
typedef struct _MSTcpServClass MSTcpServClass;
MSFilter *ms_tcp_serv_new();
#define MS_TCP_SERV(o) ((MSTcpServ*)(o))
#endif

View file

@ -1,114 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mstimer.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
static MSTimerClass *ms_timer_class=NULL;
void ms_timer_init(MSTimer *sync)
{
ms_sync_init(MS_SYNC(sync));
MS_SYNC(sync)->attached_filters=sync->filters;
memset(sync->filters,0,MSTIMER_MAX_FILTERS*sizeof(MSFilter*));
MS_SYNC(sync)->samples_per_tick=80;
ms_timer_set_interval(sync,10);
sync->state=MS_TIMER_STOPPED;
}
void ms_timer_class_init(MSTimerClass *klass)
{
ms_sync_class_init(MS_SYNC_CLASS(klass));
MS_SYNC_CLASS(klass)->max_filters=MSTIMER_MAX_FILTERS;
MS_SYNC_CLASS(klass)->synchronize=(MSSyncSyncFunc)ms_timer_synchronize;
MS_SYNC_CLASS(klass)->destroy=(MSSyncDestroyFunc)ms_timer_destroy;
/* no need to overload these function*/
MS_SYNC_CLASS(klass)->attach=ms_sync_attach_generic;
MS_SYNC_CLASS(klass)->detach=ms_sync_detach_generic;
}
void ms_timer_destroy(MSTimer *timer)
{
g_free(timer);
}
void ms_timer_synchronize(MSTimer *timer)
{
//printf("ticks=%i \n",MS_SYNC(timer)->ticks);
if (timer->state==MS_TIMER_STOPPED){
timer->state=MS_TIMER_RUNNING;
gettimeofday(&timer->orig,NULL);
timer->sync.time=0;
}
else {
gint32 diff,time;
struct timeval tv,cur;
timer->sync.time+=timer->milisec;
gettimeofday(&cur,NULL);
time=((cur.tv_usec-timer->orig.tv_usec)/1000 ) + ((cur.tv_sec-timer->orig.tv_sec)*1000 );
while((diff = timer->sync.time-time) > 0)
{
tv.tv_sec = timer->milisec/1000;
tv.tv_usec = (timer->milisec%1000)*1000;
select(0,NULL,NULL,NULL,&tv);
gettimeofday(&cur,NULL);
time=((cur.tv_usec-timer->orig.tv_usec)/1000 ) + ((cur.tv_sec-timer->orig.tv_sec)*1000 );
}
if (diff<-50) g_warning("Must catchup %i miliseconds.",-diff);
}
return;
}
MSSync *ms_timer_new()
{
MSTimer *timer;
timer=g_malloc(sizeof(MSTimer));
ms_timer_init(timer);
if (ms_timer_class==NULL)
{
ms_timer_class=g_new(MSTimerClass,1);
ms_timer_class_init(ms_timer_class);
}
MS_SYNC(timer)->klass=MS_SYNC_CLASS(ms_timer_class);
return(MS_SYNC(timer));
}
void ms_timer_set_interval(MSTimer *timer, int milisec)
{
MS_SYNC(timer)->ticks=0;
MS_SYNC(timer)->interval=milisec;
timer->interval.tv_sec=milisec/1000;
timer->interval.tv_usec=(milisec % 1000)*1000;
timer->milisec=milisec;
}

View file

@ -1,68 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSTIMER_H
#define MSTIMER_H
#include "mssync.h"
#include <sys/time.h>
#define MSTIMER_MAX_FILTERS 10
/* MSTimer derivates from MSSync base class*/
typedef struct _MSTimer
{
/* the MSSync must be the first field of the object in order to the object mechanism to work*/
MSSync sync;
MSFilter *filters[MSTIMER_MAX_FILTERS];
gint milisec; /* the interval */
struct timeval interval;
struct timeval orig;
gint state;
} MSTimer;
typedef struct _MSTimerClass
{
/* the MSSyncClass must be the first field of the class in order to the class mechanism to work*/
MSSyncClass parent_class;
} MSTimerClass;
/*private*/
#define MS_TIMER_RUNNING 1
#define MS_TIMER_STOPPED 0
void ms_timer_init(MSTimer *sync);
void ms_timer_class_init(MSTimerClass *sync);
void ms_timer_destroy(MSTimer *timer);
void ms_timer_synchronize(MSTimer *timer);
/*public*/
void ms_timer_set_interval(MSTimer *timer, gint milisec);
/* casts a MSSync object into a MSTimer */
#define MS_TIMER(sync) ((MSTimer*)(sync))
/* casts a MSSync class into a MSTimer class */
#define MS_TIMER_CLASS(klass) ((MSTimerClass*)(klass))
MSSync *ms_timer_new();
#endif

View file

@ -1,152 +0,0 @@
/*
Copyright 2003 Robert W. Brewer <rbrewer at op.net>
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mstruespeechdecoder.h"
#include "mscodec.h"
MSCodecInfo TrueSpeechinfo =
{
{
"TrueSpeech codec",
0,
MS_FILTER_AUDIO_CODEC,
ms_truespeechencoder_new,
"This is a proprietary codec by the DSP Group that is used in some "
"Windows applications. It has a good quality and bitrate. "
"It requires the Windows DLLs tssoft32.acm and "
"tsd32.dll to be available."
},
ms_truespeechencoder_new,
ms_truespeechdecoder_new,
480,
32,
8536,
8000,
116,
"TSP0",
1,
1,
};
static MSTrueSpeechDecoderClass *ms_truespeechdecoder_class = 0;
/* FOR INTERNAL USE*/
void ms_truespeechdecoder_init(MSTrueSpeechDecoder *r);
void ms_truespeechdecoder_class_init(MSTrueSpeechDecoderClass *klass);
void ms_truespeechdecoder_destroy(MSTrueSpeechDecoder *obj);
void ms_truespeechdecoder_process(MSTrueSpeechDecoder *r);
MSFilter * ms_truespeechdecoder_new(void)
{
MSTrueSpeechDecoder *r = 0;
if (!ms_truespeechdecoder_class)
{
ms_truespeechdecoder_class = g_new(MSTrueSpeechDecoderClass, 1);
ms_truespeechdecoder_class_init(ms_truespeechdecoder_class);
}
r = g_new(MSTrueSpeechDecoder, 1);
MS_FILTER(r)->klass = MS_FILTER_CLASS(ms_truespeechdecoder_class);
ms_truespeechdecoder_init(r);
return MS_FILTER(r);
}
/* FOR INTERNAL USE*/
void ms_truespeechdecoder_init(MSTrueSpeechDecoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos = r->f_inputs;
MS_FILTER(r)->outfifos = r->f_outputs;
WAVEFORMATEX* wf = ms_truespeechencoder_wf_create();
r->codec = win32codec_create(wf, 0);
free(wf);
MS_FILTER(r)->r_mingran = r->codec->min_insize;
MS_FILTER_CLASS(ms_truespeechdecoder_class)->r_maxgran =
r->codec->min_insize;
MS_FILTER_CLASS(ms_truespeechdecoder_class)->w_maxgran =
r->codec->min_outsize;
memset(r->f_inputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT);
memset(r->f_outputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT);
}
void ms_truespeechdecoder_class_init(MSTrueSpeechDecoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass), "TrueSpeechDecoder");
MS_FILTER_CLASS(klass)->max_finputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT;
MS_FILTER_CLASS(klass)->max_foutputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT;
MS_FILTER_CLASS(klass)->r_maxgran = 0; /* filled in by first instance */
MS_FILTER_CLASS(klass)->w_maxgran = 0; /* filled in by first instance */
MS_FILTER_CLASS(klass)->destroy = (MSFilterDestroyFunc)ms_truespeechdecoder_destroy;
MS_FILTER_CLASS(klass)->process = (MSFilterProcessFunc)ms_truespeechdecoder_process;
MS_FILTER_CLASS(klass)->info = MS_FILTER_INFO(&TrueSpeechinfo);
klass->driver = win32codec_create_driver(TRUESPEECH_DLL,
TRUESPEECH_FORMAT_TAG, 0);
}
void ms_truespeechdecoder_process(MSTrueSpeechDecoder *r)
{
MSFifo *fi,*fo;
gint err1;
void *s,*d;
/* process output fifos, but there is only one for this class of filter*/
fi = r->f_inputs[0];
fo = r->f_outputs[0];
if (fi)
{
err1 = ms_fifo_get_read_ptr(fi, r->codec->min_insize, &s);
if (err1 > 0)
{
err1 = ms_fifo_get_write_ptr(fo, r->codec->min_outsize, &d);
if (d)
{
signed long n;
n = win32codec_convert(r->codec,
s, r->codec->min_insize,
d, r->codec->min_outsize);
}
}
}
}
void ms_truespeechdecoder_uninit(MSTrueSpeechDecoder *obj)
{
win32codec_destroy(obj->codec);
}
void ms_truespeechdecoder_destroy(MSTrueSpeechDecoder *obj)
{
ms_truespeechdecoder_uninit(obj);
g_free(obj);
}

View file

@ -1,55 +0,0 @@
/*
Copyright (C) 2003 Robert W. Brewer <rbrewer at op.net>
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSTRUESPEECHDECODER_H
#define MSTRUESPEECHDECODER_H
#include "msfilter.h"
#include "mstruespeechencoder.h"
typedef struct _MSTrueSpeechDecoder
{
/* the MSTrueSpeechDecoder derives from MSFilter, so the MSFilter
object MUST be the first of the MSTrueSpeechDecoder object
in order for the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT];
MSFifo *f_outputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT];
Win32Codec* codec;
} MSTrueSpeechDecoder;
typedef struct _MSTrueSpeechDecoderClass
{
/* the MSTrueSpeechDecoder derives from MSFilter,
so the MSFilter class MUST be the first of the MSTrueSpechDecoder
class
in order for the class mechanism to work*/
MSFilterClass parent_class;
Win32CodecDriver* driver;
} MSTrueSpeechDecoderClass;
/* PUBLIC */
#define MS_TRUESPEECHDECODER(filter) ((MSTrueSpechMDecoder*)(filter))
#define MS_TRUESPEECHDECODER_CLASS(klass) ((MSTrueSpeechDecoderClass*)(klass))
MSFilter * ms_truespeechdecoder_new(void);
#endif

View file

@ -1,161 +0,0 @@
/*
Copyright 2003 Robert W. Brewer <rbrewer at op.net>
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mstruespeechencoder.h"
#include "mscodec.h"
#define TRUESPEECH_CBSIZE 32
extern MSCodecInfo TrueSpeechinfo;
static MSTrueSpeechEncoderClass *ms_truespeechencoder_class = 0;
/* FOR INTERNAL USE*/
void ms_truespeechencoder_init(MSTrueSpeechEncoder *r);
void ms_truespeechencoder_class_init(MSTrueSpeechEncoderClass *klass);
void ms_truespeechencoder_destroy(MSTrueSpeechEncoder *obj);
void ms_truespeechencoder_process(MSTrueSpeechEncoder *r);
MSFilter * ms_truespeechencoder_new(void)
{
MSTrueSpeechEncoder *r = 0;
if (!ms_truespeechencoder_class)
{
ms_truespeechencoder_class = g_new(MSTrueSpeechEncoderClass, 1);
ms_truespeechencoder_class_init(ms_truespeechencoder_class);
}
r = g_new(MSTrueSpeechEncoder, 1);
MS_FILTER(r)->klass = MS_FILTER_CLASS(ms_truespeechencoder_class);
ms_truespeechencoder_init(r);
return MS_FILTER(r);
}
/* FOR INTERNAL USE*/
void ms_truespeechencoder_init(MSTrueSpeechEncoder *r)
{
ms_filter_init(MS_FILTER(r));
MS_FILTER(r)->infifos = r->f_inputs;
MS_FILTER(r)->outfifos = r->f_outputs;
WAVEFORMATEX* wf = ms_truespeechencoder_wf_create();
r->codec = win32codec_create(wf, 1);
free(wf);
MS_FILTER(r)->r_mingran = r->codec->min_insize;
MS_FILTER_CLASS(ms_truespeechencoder_class)->r_maxgran =
r->codec->min_insize;
MS_FILTER_CLASS(ms_truespeechencoder_class)->w_maxgran =
r->codec->min_outsize;
memset(r->f_inputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT);
memset(r->f_outputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT);
}
void ms_truespeechencoder_class_init(MSTrueSpeechEncoderClass *klass)
{
ms_filter_class_init(MS_FILTER_CLASS(klass));
ms_filter_class_set_name(MS_FILTER_CLASS(klass), "TrueSpeechEncoder");
MS_FILTER_CLASS(klass)->max_finputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT;
MS_FILTER_CLASS(klass)->max_foutputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT;
MS_FILTER_CLASS(klass)->r_maxgran = 0; /* filled in by first instance */
MS_FILTER_CLASS(klass)->w_maxgran = 0; /* filled in by first instance */
MS_FILTER_CLASS(klass)->destroy = (MSFilterDestroyFunc)ms_truespeechencoder_destroy;
MS_FILTER_CLASS(klass)->process = (MSFilterProcessFunc)ms_truespeechencoder_process;
MS_FILTER_CLASS(klass)->info = MS_FILTER_INFO(&TrueSpeechinfo);
klass->driver = win32codec_create_driver(TRUESPEECH_DLL,
TRUESPEECH_FORMAT_TAG, 1);
}
void ms_truespeechencoder_process(MSTrueSpeechEncoder *r)
{
MSFifo *fi,*fo;
int err1;
void *s,*d;
/* process output fifos, but there is only one for this class of filter*/
fi = r->f_inputs[0];
fo = r->f_outputs[0];
if (fi)
{
err1 = ms_fifo_get_read_ptr(fi, r->codec->min_insize, &s);
if (err1 > 0)
{
err1 = ms_fifo_get_write_ptr(fo, r->codec->min_outsize, &d);
if (d)
{
signed long n;
n = win32codec_convert(r->codec,
s, r->codec->min_insize,
d, r->codec->min_outsize);
}
}
}
}
void ms_truespeechencoder_uninit(MSTrueSpeechEncoder *obj)
{
win32codec_destroy(obj->codec);
}
void ms_truespeechencoder_destroy(MSTrueSpeechEncoder *obj)
{
ms_truespeechencoder_uninit(obj);
g_free(obj);
}
WAVEFORMATEX* ms_truespeechencoder_wf_create()
{
WAVEFORMATEX* ts_wf = 0;
long* iptr = 0;
ts_wf = malloc(sizeof(WAVEFORMATEX) + TRUESPEECH_CBSIZE);
if (!ts_wf)
{
return 0;
}
memset(ts_wf, 0, sizeof(*ts_wf) + TRUESPEECH_CBSIZE);
ts_wf->wFormatTag = TRUESPEECH_FORMAT_TAG;
ts_wf->nChannels = 1;
ts_wf->nSamplesPerSec = 8000;
ts_wf->wBitsPerSample = 1;
ts_wf->nBlockAlign = 32;
ts_wf->nAvgBytesPerSec = 1067;
ts_wf->cbSize = TRUESPEECH_CBSIZE;
/* write extra data needed by TrueSpeech codec found
from examining a TrueSpeech .wav file header
*/
iptr = (long*)(ts_wf + 1);
*iptr = 0x00f00001;
return ts_wf;
}

View file

@ -1,62 +0,0 @@
/*
Copyright (C) 2003 Robert W. Brewer <rbrewer at op.net>
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSTRUESPEECHENCODER_H
#define MSTRUESPEECHENCODER_H
#include "msfilter.h"
#include <win32codec.h>
#define MS_TRUESPEECH_CODEC_MAX_IN_OUT 1 /* max inputs/outputs per filter*/
#define TRUESPEECH_FORMAT_TAG 0x22
#define TRUESPEECH_DLL "tssoft32.acm"
typedef struct _MSTrueSpeechEncoder
{
/* the MSTrueSpeechEncoder derives from MSFilter, so the MSFilter
object MUST be the first of the MSTrueSpeechEncoder object
in order for the object mechanism to work*/
MSFilter filter;
MSFifo *f_inputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT];
MSFifo *f_outputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT];
Win32Codec* codec;
} MSTrueSpeechEncoder;
typedef struct _MSTrueSpeechEncoderClass
{
/* the MSTrueSpeechEncoder derives from MSFilter,
so the MSFilter class MUST be the first of the MSTrueSpechEncoder
class
in order for the class mechanism to work*/
MSFilterClass parent_class;
Win32CodecDriver* driver;
} MSTrueSpeechEncoderClass;
/* PUBLIC */
#define MS_TRUESPEECHENCODER(filter) ((MSTrueSpechMEncoder*)(filter))
#define MS_TRUESPEECHENCODER_CLASS(klass) ((MSTrueSpeechEncoderClass*)(klass))
MSFilter * ms_truespeechencoder_new(void);
/* for internal use only */
WAVEFORMATEX* ms_truespeechencoder_wf_create();
#endif

View file

@ -1,61 +0,0 @@
/*
The mediastreamer library aims at providing modular media processing and I/O
for linphone, but also for any telephony application.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library 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.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MSUTILS_H
#define MSUTILS_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_GLIB
#include <glib.h>
#else
#include <uglib.h>
#endif
#include <errno.h>
#ifndef ENODATA
/* this is for freeBSD .*/
#define ENODATA EWOULDBLOCK
#endif
#ifdef MS_DEBUG
#define ms_trace g_message
#else
#define ms_trace(...)
#endif
#define ms_warning g_warning
#define ms_error g_error
#define VIDEO_SIZE_CIF_W 352
#define VIDEO_SIZE_CIF_H 288
#define VIDEO_SIZE_QCIF_W 176
#define VIDEO_SIZE_QCIF_H 144
#define VIDEO_SIZE_4CIF_W 704
#define VIDEO_SIZE_4CIF_H 576
#define VIDEO_SIZE_MAX_W VIDEO_SIZE_4CIF_W
#define VIDEO_SIZE_MAX_H VIDEO_SIZE_4CIF_H
#endif

Some files were not shown because too many files have changed in this diff Show more