From c29c0d54f8ca0a9b3ba73970f46688e9f1757af5 Mon Sep 17 00:00:00 2001
From: smorlat <smorlat@3f6dc0c8-ddfe-455d-9043-3cd528dc4637>
Date: Mon, 13 Jul 2009 20:26:18 +0000
Subject: [PATCH] equalizer - work in progress.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@535 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
---
 linphone/INSTALL                              |  50 +++---
 linphone/mediastreamer2/INSTALL               |  50 +++---
 .../include/mediastreamer2/Makefile.am        |   3 +-
 .../include/mediastreamer2/allfilters.h       |   3 +-
 linphone/mediastreamer2/src/Makefile.am       |   3 +-
 linphone/mediastreamer2/src/dsptools.c        |   2 +-
 linphone/mediastreamer2/src/equalizer.c       | 163 +++++++++++++++---
 linphone/po/Makefile.in.in                    |   4 +-
 8 files changed, 204 insertions(+), 74 deletions(-)
 mode change 100755 => 100644 linphone/INSTALL
 mode change 100755 => 100644 linphone/mediastreamer2/INSTALL
 mode change 100755 => 100644 linphone/po/Makefile.in.in

diff --git a/linphone/INSTALL b/linphone/INSTALL
old mode 100755
new mode 100644
index 5458714e1e..23e5f25d0e
--- a/linphone/INSTALL
+++ b/linphone/INSTALL
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
 
 This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
@@ -10,10 +10,7 @@ unlimited permission to copy, distribute and modify it.
 Basic Installation
 ==================
 
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
+These are generic installation instructions.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
@@ -26,9 +23,9 @@ debugging `configure').
 
    It can also use an optional file (typically called `config.cache'
 and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
+the results of its tests to speed up reconfiguring.  (Caching is
 disabled by default to prevent problems with accidental use of stale
-cache files.
+cache files.)
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
@@ -38,17 +35,20 @@ some point `config.cache' contains results you don't want to keep, you
 may remove or edit it.
 
    The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
 
 The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
 
-     Running `configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -78,7 +78,7 @@ details on some of the pertinent environment variables.
 by setting variables in the command line or in the environment.  Here
 is an example:
 
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
 
    *Note Defining Variables::, for more details.
 
@@ -87,15 +87,17 @@ Compiling For Multiple Architectures
 
 You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
 source code in the directory that `configure' is in and in `..'.
 
-   With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
 
 Installation Names
 ==================
@@ -188,12 +190,12 @@ them in the `configure' command line, using `VAR=value'.  For example:
      ./configure CC=/usr/local2/bin/gcc
 
 causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
+overridden in the site shell script).  Here is a another example:
 
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug.  Until the bug is fixed you can use this workaround:
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
 
-     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
 
 `configure' Invocation
 ======================
diff --git a/linphone/mediastreamer2/INSTALL b/linphone/mediastreamer2/INSTALL
old mode 100755
new mode 100644
index 5458714e1e..23e5f25d0e
--- a/linphone/mediastreamer2/INSTALL
+++ b/linphone/mediastreamer2/INSTALL
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
 
 This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
@@ -10,10 +10,7 @@ unlimited permission to copy, distribute and modify it.
 Basic Installation
 ==================
 
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
+These are generic installation instructions.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
@@ -26,9 +23,9 @@ debugging `configure').
 
    It can also use an optional file (typically called `config.cache'
 and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
+the results of its tests to speed up reconfiguring.  (Caching is
 disabled by default to prevent problems with accidental use of stale
-cache files.
+cache files.)
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
@@ -38,17 +35,20 @@ some point `config.cache' contains results you don't want to keep, you
 may remove or edit it.
 
    The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
 
 The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
 
-     Running `configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -78,7 +78,7 @@ details on some of the pertinent environment variables.
 by setting variables in the command line or in the environment.  Here
 is an example:
 
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
 
    *Note Defining Variables::, for more details.
 
@@ -87,15 +87,17 @@ Compiling For Multiple Architectures
 
 You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
 source code in the directory that `configure' is in and in `..'.
 
-   With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
 
 Installation Names
 ==================
@@ -188,12 +190,12 @@ them in the `configure' command line, using `VAR=value'.  For example:
      ./configure CC=/usr/local2/bin/gcc
 
 causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
+overridden in the site shell script).  Here is a another example:
 
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug.  Until the bug is fixed you can use this workaround:
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
 
-     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
 
 `configure' Invocation
 ======================
diff --git a/linphone/mediastreamer2/include/mediastreamer2/Makefile.am b/linphone/mediastreamer2/include/mediastreamer2/Makefile.am
index 3fb6087260..83343ab969 100644
--- a/linphone/mediastreamer2/include/mediastreamer2/Makefile.am
+++ b/linphone/mediastreamer2/include/mediastreamer2/Makefile.am
@@ -21,7 +21,8 @@ mediastreamer2_include_HEADERS= ice.h \
 				mstee.h \
 				rfc3984.h \
 				mswebcam.h \
-				dsptools.h
+				dsptools.h \
+				msequalizer.h
 
 EXTRA_DIST=$(mediastreamer2_include_HEADERS)
 
diff --git a/linphone/mediastreamer2/include/mediastreamer2/allfilters.h b/linphone/mediastreamer2/include/mediastreamer2/allfilters.h
index 82664afd24..3643665646 100644
--- a/linphone/mediastreamer2/include/mediastreamer2/allfilters.h
+++ b/linphone/mediastreamer2/include/mediastreamer2/allfilters.h
@@ -85,7 +85,8 @@ typedef enum MSFilterId{
 	MS_VOID_SINK_ID,
 	MS_DSCAP_ID,
 	MS_AQ_READ_ID,
-	MS_AQ_WRITE_ID
+	MS_AQ_WRITE_ID,
+	MS_EQUALIZER_ID
 } MSFilterId;
 
 
diff --git a/linphone/mediastreamer2/src/Makefile.am b/linphone/mediastreamer2/src/Makefile.am
index faf0f61986..8c1d0070a5 100644
--- a/linphone/mediastreamer2/src/Makefile.am
+++ b/linphone/mediastreamer2/src/Makefile.am
@@ -35,7 +35,8 @@ libmediastreamer_la_SOURCES=	mscommon.c     \
 				_kiss_fft_guts.h \
 				kiss_fft.h \
 				kiss_fftr.c \
-				kiss_fftr.h
+				kiss_fftr.h \
+				equalizer.c
 
 #dummy c++ file to force libtool to use c++ linking (because of msdscap-mingw.cc)
 nodist_EXTRA_libmediastreamer_la_SOURCES = dummy.cxx
diff --git a/linphone/mediastreamer2/src/dsptools.c b/linphone/mediastreamer2/src/dsptools.c
index 184f0afcb7..d06a7ebdb6 100644
--- a/linphone/mediastreamer2/src/dsptools.c
+++ b/linphone/mediastreamer2/src/dsptools.c
@@ -229,7 +229,7 @@ void ms_fir_mem16(const ms_word16_t *x, const ms_coef_t *num, ms_word16_t *y, in
    for (i=0;i<N;i++)
    {
       xi=x[i];
-      yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767));
+      yi = EXTRACT16(SATURATE(ADD32(EXTEND32(xi),PSHR32(mem[0],LPC_SHIFT)),32767));
       for (j=0;j<ord-1;j++)
       {
          mem[j] = MAC16_16(mem[j+1], num[j],xi);
diff --git a/linphone/mediastreamer2/src/equalizer.c b/linphone/mediastreamer2/src/equalizer.c
index 4a585f83b6..937ac49fa6 100644
--- a/linphone/mediastreamer2/src/equalizer.c
+++ b/linphone/mediastreamer2/src/equalizer.c
@@ -17,21 +17,25 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
-#include <mediastreamer2/msfilter.h>
+#include <mediastreamer2/msequalizer.h>
 #include <mediastreamer2/dsptools.h>
 
+#include <math.h>
+
 #define GAIN_ZERODB 22000
 
 
 typedef struct _EqualizerState{
 	int rate;
 	int nfft; //number of fft points in time
-	int16_t *fft_cpx;
+	ms_word16_t *fft_cpx;
 	int fir_len;
-	int16_t *fir;
+	ms_word16_t *fir;
+	ms_mem_t *mem; /*memories for filtering computations*/
+	bool_t needs_update;
 } EqualizerState;
 
-static void equalizer_flatten(EqualizerState *s){
+static void equalizer_state_flatten(EqualizerState *s){
 	int i;
 	for(i=0;i<s->nfft;i+=2)
 		s->fft_cpx[i]=GAIN_ZERODB;
@@ -39,13 +43,22 @@ static void equalizer_flatten(EqualizerState *s){
 
 static EqualizerState * equalizer_state_new(int nfft){
 	EqualizerState *s=ms_new0(EqualizerState,1);
-	int i;
 	s->rate=8000;
 	s->nfft=nfft;
-	s->fft_cpx=ms_new0(int16_t,s->nfft);
-	equalizer_flatten(s);
+	s->fft_cpx=ms_new0(ms_word16_t,s->nfft);
+	equalizer_state_flatten(s);
 	s->fir_len=s->nfft;
-	s->fir=ms_new(int16_t,s->fir_len);
+	s->fir=ms_new(ms_word16_t,s->fir_len);
+	s->mem=ms_new0(ms_mem_t,s->fir_len);
+	s->needs_update=TRUE;
+	return s;
+}
+
+static void equalizer_state_destroy(EqualizerState *s){
+	ms_free(s->fft_cpx);
+	ms_free(s->fir);
+	ms_free(s->mem);
+	ms_free(s);
 }
 
 static int equalizer_state_hz_to_index(EqualizerState *s, int hz){
@@ -62,59 +75,169 @@ static int equalizer_state_hz_to_index(EqualizerState *s, int hz){
 	return ret;
 }
 
-static float gain_float(int16_t val){
+static float gain_float(ms_word16_t val){
 	return (float)val/22000.0;
 }
 
-static int16_t gain_int16(float val){
+static ms_word16_t gain_int16(float val){
 	int ret=(int)(val*22000.0);
 	if (ret>=32767) ret=32767;
-	return (int16_t)ret;
+	return (ms_word16_t)ret;
 }
 
-static float equalizer_get(EqualizerState *s, int freqhz){
+static float equalizer_state_get(EqualizerState *s, int freqhz){
 	int idx=equalizer_state_hz_to_index(s,freqhz);
 	if (idx>=0) return gain_float(s->fft_cpx[idx*2]);
 	return 0;
 }
 
 /* return the frequency band width we want to control around hz*/
-static void equalizer_get_band(EqualizerState *s, int hz, int *low_index, int *high_index){
+static void equalizer_state_get_band(EqualizerState *s, int hz, int *low_index, int *high_index){
 	int half_band=(int)((float)hz*0.1);
 	*low_index=equalizer_state_hz_to_index(s,hz-half_band);
 	*high_index=equalizer_state_hz_to_index(s,hz+half_band);
 }
 
-static int16_t equalizer_set(EqualizerState *s, int freqhz, float gain){
+static void equalizer_state_set(EqualizerState *s, int freqhz, float gain){
 	int low,high;
 	int i;
-	equalizer_get_band(s,freqhz,&low,&high);
+	equalizer_state_get_band(s,freqhz,&low,&high);
 	for(i=low;i<=high;++i){
 		ms_message("Setting gain %f for freq_index %i (freqhz=%i)",gain,i,freqhz);
 		s->fft_cpx[i*2]=gain_int16(gain);
 	}
+	s->needs_update=TRUE;
 }
 
-static void dump_table(int16_t *t, int len){
+static void dump_table(ms_word16_t *t, int len){
 	int i;
 	for(i=0;i<len;i++)
+#ifdef MS_FIXED_POINT
 		ms_message("[%i]\t%i",i,t[i]);
+#else
+		ms_message("[%i]\t%f",i,t[i]);
+#endif
 }
 
-static void apodize(int16_t *s, int len){
+/*
+ *hamming:
+ * 0.54 - 0.46*cos(2*M_PI*t/T)
+ *
+ * blackman
+ * 0.42 - 0.5*cos(2*M_PI*t/T) + 0.08*cos(4*M_PI*t/T)
+*/
+
+static void apodize(ms_word16_t *s, int len){
 	int i;
 	float x;
+	float w;
 	for(i=0;i<len;++i){
-		x=(float)i/
-		s[i]=cos
+		x=(float)i*2*M_PI/(float)len;
+		w=0.42 - (0.5*cos(x)) + (0.08*cos(2*x));
+		s[i]=w*(float)s[i];
 	}	
 }
 
-static void equalizer_compute_impulse_response(EqualizerState *s){
+static void equalizer_state_compute_impulse_response(EqualizerState *s){
 	void *fft_handle=ms_fft_init(s->nfft);
 	ms_ifft(fft_handle,s->fft_cpx,s->fir);
 	ms_message("Inverse fft result:");
 	dump_table(s->fir,s->fir_len);
 	apodize(s->fir,s->fir_len);
+	ms_message("Apodized impulse response:");
+	dump_table(s->fir,s->fir_len);
+	s->needs_update=FALSE;
+}
+
+
+
+#ifdef MS_FIXED_POINT
+#define INT16_TO_WORD16(i,w,l) w=(i)
+#define WORD16_TO_INT16(i,w,l) i=(w)
+#else
+
+static void int16_to_word16(const int16_t *is, ms_word16_t *w, int l){
+	int i;
+	for(i=0;i<l;++i){
+		w[i]=(ms_word16_t)is[i];
+	}
+}
+
+static void word16_to_int16(const ms_word16_t *w, int16_t *is, int l){
+	int i;
+	for (i=0;i<l;++i)
+		is[i]=(int16_t)w[i];
+}
+
+#define INT16_TO_WORD16(i,w,l) w=(ms_word16_t*)alloca(sizeof(ms_word16_t)*(l));int16_to_word16(i,w,l)
+#define WORD16_TO_INT16(w,i,l) word16_to_int16(w,i,l)
+#endif
+
+static void equalizer_state_run(EqualizerState *s, int16_t *samples, int nsamples){
+	if (s->needs_update)
+		equalizer_state_compute_impulse_response(s);
+	ms_word16_t *w;
+	INT16_TO_WORD16(samples,w,nsamples);
+	ms_fir_mem16(w,s->fir,w,nsamples,s->fir_len,s->mem);
+	WORD16_TO_INT16(w,samples,nsamples);
+}
+
+
+void equalizer_init(MSFilter *f){
+	f->data=equalizer_state_new(128);
+}
+
+void equalizer_uninit(MSFilter *f){
+	equalizer_state_destroy((EqualizerState*)f->data);
+}
+
+void equalizer_process(MSFilter *f){
+	mblk_t *m;
+	EqualizerState *s=(EqualizerState*)f->data;
+	while((m=ms_queue_get(f->inputs[0]))!=NULL){
+		equalizer_state_run(s,(int16_t*)m->b_rptr,(m->b_wptr-m->b_rptr)/2);
+		ms_queue_put(f->outputs[0],m);
+	}
+}
+
+int equalizer_set_gain(MSFilter *f, void *data){
+	EqualizerState *s=(EqualizerState*)f->data;
+	MSEqualizerGain *d=(MSEqualizerGain*)data;
+	equalizer_state_set(s,d->frequency,d->gain);
+	return 0;
+}
+
+int equalizer_get_gain(MSFilter *f, void *data){
+	EqualizerState *s=(EqualizerState*)f->data;
+	MSEqualizerGain *d=(MSEqualizerGain*)data;
+	d->gain=equalizer_state_get(s,d->frequency);
+	return 0;
+}
+
+int equalizer_set_rate(MSFilter *f, void *data){
+	EqualizerState *s=(EqualizerState*)f->data;
+	s->rate=*(int*)data;
+	return 0;
 }
 
+static MSFilterMethod equalizer_methods[]={
+	{	MS_EQUALIZER_SET_GAIN		,	equalizer_set_gain	},
+	{	MS_EQUALIZER_GET_GAIN		,	equalizer_get_gain	},
+	{	MS_FILTER_SET_SAMPLE_RATE	,	equalizer_set_rate	},
+	{	0				,	NULL			}
+};
+
+MSFilterDesc ms_equalizer_desc={
+	.id= MS_EQUALIZER_ID,
+	.name="MSEqualizer",
+	.text=N_("Parametric sound equalizer."),
+	.category=MS_FILTER_OTHER,
+	.ninputs=1,
+	.noutputs=1,
+	.init=equalizer_init,
+	.process=equalizer_process,
+	.uninit=equalizer_uninit,
+	.methods=equalizer_methods
+};
+
+MS_FILTER_DESC_EXPORT(ms_equalizer_desc)
diff --git a/linphone/po/Makefile.in.in b/linphone/po/Makefile.in.in
old mode 100755
new mode 100644
index 57ef267b3e..402a25f7ac
--- a/linphone/po/Makefile.in.in
+++ b/linphone/po/Makefile.in.in
@@ -21,7 +21,7 @@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
 PACKAGE = @PACKAGE@
 VERSION = @VERSION@
 
-SHELL = /bin/sh
+SHELL = @SHELL@
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -56,7 +56,7 @@ ALL_LINGUAS = @ALL_LINGUAS@
 
 PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
 
-USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep ^$$lang$$`"; then printf "$$lang "; fi; done; fi)
+USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi)
 
 USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
 
-- 
GitLab