Problem

Files of type .vmo need to be converted to something else, e.g. .wav. This utility is hidden in this SieFS (Siemens File System) project, which attempts to allow mounting of a mobile phone under Linux. Project home page: http://chaos.allsiemens.com/download/siefs-0.5.tar.gz

It didn't compile out of the box because SieFS depends on FUSE, which was not installed and does not HAVE to be installed for the conversion utility as such. However, ./configure did not want to continue without FUSE.

Mmmm.. The solution comes from the 'when-harry-met-sally-dept.': we simply fake the existence of the necessary file. The configure-script looks foir a file .../include/fuse/fuse.h which is to contain at least the text "(*release)". Well, let's provide that than.

Below is the script of my experiment. My input in bold. There is also a section on Endian-ness; it appeared that the converted files were not converted correctly on a Mac.

Peter Fokker / <peter (at) berestijn (dot) nl> / 2005-08-03

Compiling vmo2wav 2005-08-02

Script started on Tue 02 Aug 2005 06:27:18 PM CEST
[peter@woozle siefs]$ date
Tue Aug  2 18:27:23 CEST 2005
[peter@woozle siefs]$ pwd
/home/peter/tmp/siefs
[peter@woozle siefs]$ ls -l
total 156
-rw-------    1 peter    users       44268 2005-08-02 18:27 05-08-02_15-22-55.vmo
-rw-------    1 peter    users      112466 2005-08-02 18:17 siefs-0.5.tar.gz
[peter@woozle siefs]$ tar zxvf siefs-0.5.tar.gz
siefs-0.5/
siefs-0.5/Makefile.in
siefs-0.5/stamp-h.in
siefs-0.5/configure
siefs-0.5/Makefile.am
siefs-0.5/configure.in
siefs-0.5/INSTALL
siefs-0.5/NEWS
siefs-0.5/README
siefs-0.5/AUTHORS
siefs-0.5/ChangeLog
siefs-0.5/siefs/
siefs-0.5/siefs/Makefile.am
siefs-0.5/siefs/transport.h
siefs-0.5/siefs/Makefile.in
siefs-0.5/siefs/comm.c
siefs-0.5/siefs/siefs.c
siefs-0.5/siefs/comm.h
siefs-0.5/siefs/crcmodel.c
siefs-0.5/siefs/crcmodel.h
siefs-0.5/siefs/obex.c
siefs-0.5/siefs/obex.h
siefs-0.5/siefs/slink.c
siefs-0.5/siefs/transport.c
siefs-0.5/siefs/charset.c
siefs-0.5/siefs/charset.h
siefs-0.5/COPYING
siefs-0.5/converter/
siefs-0.5/converter/gsm_decode.c
siefs-0.5/converter/decode.c
siefs-0.5/converter/short_term.c
siefs-0.5/converter/long_term.c
siefs-0.5/converter/rpe.c
siefs-0.5/converter/table.c
siefs-0.5/converter/gsm.h
siefs-0.5/converter/private.h
siefs-0.5/converter/proto.h
siefs-0.5/converter/unproto.h
siefs-0.5/converter/add.c
siefs-0.5/converter/gsm_create.c
siefs-0.5/converter/README
siefs-0.5/converter/gsm_destroy.c
siefs-0.5/converter/gsm_option.c
siefs-0.5/converter/Makefile.in
siefs-0.5/converter/vmconvert.c
siefs-0.5/converter/vmo2wav.c
siefs-0.5/converter/COPYRIGHT
siefs-0.5/converter/Makefile.am
siefs-0.5/converter/vmconvert.h
siefs-0.5/stamp-h
siefs-0.5/acconfig.h
siefs-0.5/aclocal.m4
siefs-0.5/config.h.in
siefs-0.5/install-sh
siefs-0.5/missing
siefs-0.5/mkinstalldirs
siefs-0.5/depcomp
[peter@woozle siefs]$ cd siefs-0.5
[peter@woozle siefs-0.5]$ mkdir include
[peter@woozle siefs-0.5]$ mkdir include/fuse
[peter@woozle siefs-0.5]$ echo '(*release)' >include/fuse/fuse.h
[peter@woozle siefs-0.5]$ ./configure --with-fuse=$(pwd)
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
/home/peter/tmp/siefs/siefs-0.5/missing: Unknown `--run' option
Try `/home/peter/tmp/siefs/siefs-0.5/missing --help' for more information
configure: WARNING: `missing' script is too old or missing
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for ranlib... ranlib
checking fuse installation... /home/peter/tmp/siefs/siefs-0.5
configure: creating ./config.status
config.status: creating Makefile
config.status: creating siefs/Makefile
config.status: creating converter/Makefile
config.status: creating config.h
config.status: executing depfiles commands
[peter@woozle siefs-0.5]$ cd converter/
[peter@woozle converter]$ make
source='add.c' object='add.o' libtool=no \
depfile='.deps/add.Po' tmpdepfile='.deps/add.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'add.c' || echo './'`add.c
source='decode.c' object='decode.o' libtool=no \
depfile='.deps/decode.Po' tmpdepfile='.deps/decode.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'decode.c' || echo './'`decode.c
source='gsm_create.c' object='gsm_create.o' libtool=no \
depfile='.deps/gsm_create.Po' tmpdepfile='.deps/gsm_create.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'gsm_create.c' || echo './'`gsm_create.c
gsm_create.c:15: warning: conflicting types for built-in function `memset'
source='gsm_decode.c' object='gsm_decode.o' libtool=no \
depfile='.deps/gsm_decode.Po' tmpdepfile='.deps/gsm_decode.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'gsm_decode.c' || echo './'`gsm_decode.c
source='gsm_destroy.c' object='gsm_destroy.o' libtool=no \
depfile='.deps/gsm_destroy.Po' tmpdepfile='.deps/gsm_destroy.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'gsm_destroy.c' || echo './'`gsm_destroy.c
source='gsm_option.c' object='gsm_option.o' libtool=no \
depfile='.deps/gsm_option.Po' tmpdepfile='.deps/gsm_option.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'gsm_option.c' || echo './'`gsm_option.c
source='long_term.c' object='long_term.o' libtool=no \
depfile='.deps/long_term.Po' tmpdepfile='.deps/long_term.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'long_term.c' || echo './'`long_term.c
long_term.c: In function `Gsm_Long_Term_Predictor':
long_term.c:867: warning: unused parameter `S'
source='rpe.c' object='rpe.o' libtool=no \
depfile='.deps/rpe.Po' tmpdepfile='.deps/rpe.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'rpe.c' || echo './'`rpe.c
rpe.c: In function `Gsm_RPE_Encoding':
rpe.c:449: warning: unused parameter `S'
rpe.c: In function `Gsm_RPE_Decoding':
rpe.c:472: warning: unused parameter `S'
source='short_term.c' object='short_term.o' libtool=no \
depfile='.deps/short_term.Po' tmpdepfile='.deps/short_term.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'short_term.c' || echo './'`short_term.c
source='table.c' object='table.o' libtool=no \
depfile='.deps/table.Po' tmpdepfile='.deps/table.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'table.c' || echo './'`table.c
source='vmconvert.c' object='vmconvert.o' libtool=no \
depfile='.deps/vmconvert.Po' tmpdepfile='.deps/vmconvert.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'vmconvert.c' || echo './'`vmconvert.c
source='vmo2wav.c' object='vmo2wav.o' libtool=no \
depfile='.deps/vmo2wav.Po' tmpdepfile='.deps/vmo2wav.TPo' \
depmode=gcc3 /bin/sh ../depcomp \
gcc -DHAVE_CONFIG_H -I. -I. -I..   -I/home/peter/tmp/siefs/siefs-0.5/include  -Wall -W -g -O2 -c `test -f 'vmo2wav.c' || echo './'`vmo2wav.c
gcc  -Wall -W -g -O2  -L/home/peter/tmp/siefs/siefs-0.5/lib -o vmo2wav  add.o decode.o gsm_create.o gsm_decode.o gsm_destroy.o gsm_option.o long_term.o rpe.o short_term.o table.o vmconvert.o vmo2wav.o  
[peter@woozle converter]$ ls -lart
total 431
-rw-r--r--    1 peter    users        1443 2005-04-04 06:02 vmo2wav.c
-rw-r--r--    1 peter    users         187 2005-04-04 06:02 vmconvert.h
-rw-r--r--    1 peter    users        1444 2005-04-04 06:02 vmconvert.c
-rw-r--r--    1 peter    users         476 2005-04-04 06:02 unproto.h
-rw-r--r--    1 peter    users        2151 2005-04-04 06:02 table.c
-rw-r--r--    1 peter    users       10406 2005-04-04 06:02 short_term.c
-rw-r--r--    1 peter    users       11064 2005-04-04 06:02 rpe.c
-rw-r--r--    1 peter    users        1671 2005-04-04 06:02 README
-rw-r--r--    1 peter    users        1611 2005-04-04 06:02 proto.h
-rw-r--r--    1 peter    users        7787 2005-04-04 06:02 private.h
-rw-r--r--    1 peter    users       23591 2005-04-04 06:02 long_term.c
-rw-r--r--    1 peter    users        1209 2005-04-04 06:02 gsm_option.c
-rw-r--r--    1 peter    users        1681 2005-04-04 06:02 gsm.h
-rw-r--r--    1 peter    users         573 2005-04-04 06:02 gsm_destroy.c
-rw-r--r--    1 peter    users       10670 2005-04-04 06:02 gsm_decode.c
-rw-r--r--    1 peter    users         860 2005-04-04 06:02 gsm_create.c
-rw-r--r--    1 peter    users        1574 2005-04-04 06:02 decode.c
-rw-r--r--    1 peter    users         690 2005-04-04 06:02 COPYRIGHT
-rw-r--r--    1 peter    users        5560 2005-04-04 06:02 add.c
-rw-r--r--    1 peter    users         283 2005-04-04 06:43 Makefile.am
-rw-r--r--    1 peter    users       10616 2005-04-05 16:36 Makefile.in
-rw-r--r--    1 peter    users        9973 2005-08-02 18:29 Makefile
drwxr-xr-x    5 peter    users         808 2005-08-02 18:29 ..
-rw-r--r--    1 peter    users       10996 2005-08-02 18:29 decode.o
-rw-r--r--    1 peter    users       14428 2005-08-02 18:29 add.o
-rw-r--r--    1 peter    users       11788 2005-08-02 18:29 gsm_decode.o
-rw-r--r--    1 peter    users       10248 2005-08-02 18:29 gsm_create.o
-rw-r--r--    1 peter    users        9896 2005-08-02 18:29 gsm_option.o
-rw-r--r--    1 peter    users        9256 2005-08-02 18:29 gsm_destroy.o
-rw-r--r--    1 peter    users       16324 2005-08-02 18:29 rpe.o
-rw-r--r--    1 peter    users       15464 2005-08-02 18:29 long_term.o
-rw-r--r--    1 peter    users       10144 2005-08-02 18:29 table.o
-rw-r--r--    1 peter    users       16136 2005-08-02 18:29 short_term.o
-rw-r--r--    1 peter    users       23976 2005-08-02 18:29 vmo2wav.o
-rwxr-xr-x    1 peter    users       97960 2005-08-02 18:29 vmo2wav
-rw-r--r--    1 peter    users       14984 2005-08-02 18:29 vmconvert.o
drwxr-xr-x    2 peter    users         408 2005-08-02 18:29 .deps
drwxr-xr-x    3 peter    users        1088 2005-08-02 18:29 .
[peter@woozle converter]$ cd ../..
[peter@woozle siefs]$ ls -l
total 157
-rw-------    1 peter    users       44268 2005-08-02 18:27 05-08-02_15-22-55.vmo
drwxr-xr-x    5 peter    users         808 2005-08-02 18:29 siefs-0.5
-rw-------    1 peter    users      112466 2005-08-02 18:17 siefs-0.5.tar.gz
[peter@woozle siefs]$ siefs-0.5/converter/vmo2wav 05-08-02_15-22-55.vmo
[peter@woozle siefs]$ ls -lart
total 567
-rw-------    1 peter    users      112466 2005-08-02 18:17 siefs-0.5.tar.gz
-rw-------    1 peter    users       44268 2005-08-02 18:27 05-08-02_15-22-55.vmo
drwxr-xr-x   11 peter    users         832 2005-08-02 18:27 ..
drwxr-xr-x    5 peter    users         808 2005-08-02 18:29 siefs-0.5
-rw-r--r--    1 peter    users      416684 2005-08-02 18:31 05-08-02_15-22-55.wav
drwxr-xr-x    3 peter    users         192 2005-08-02 18:31 .
[peter@woozle siefs]$ play 05-08-02_15-22-55.wav
[peter@woozle siefs]$ date
Tue Aug  2 18:32:47 CEST 2005
[peter@woozle siefs]$ 
Script done on Tue 02 Aug 2005 06:32:57 PM CEST

Endian-ness

Unfortunately there was a problem with Endian-ness. It appears that the original convertor was strictly Little Endian (ie. Intel). Oops. Didn't work on a Mac. After Googling a bit I found two useful links.

With a few minor changes in 2 files I managed to create a working convertor on a Mac. I have the modified files here: vmconvert.h and vmconvert.c. Here are the diffs, too: patch1.txt and patch2.txt.

Patches voor vmconvert.c

--- vmconvert.c-orig	2005-08-03 13:14:36.000000000 +0200
+++ vmconvert.c	2005-08-03 13:05:14.000000000 +0200
@@ -1,3 +1,5 @@
+/* vmconvert.c - adapted by Peter Fokker <peter@berestijn.nl> ; deal with endianness  2005-08-03 */
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -48,6 +50,17 @@
 	rh->filesize = sizeof(struct riff_header) + wav_data_size - 8;
 	rh->datasize = wav_data_size;
 
+	/* take care of endian anomaly; make it little endian */
+	rh->filesize	= endian_l(rh->filesize);
+	rh->fmthsize	= endian_l(rh->fmthsize);
+	rh->format	= endian_s(rh->format);
+	rh->channels	= endian_s(rh->channels);
+	rh->rate	= endian_l(rh->rate);
+	rh->bsec	= endian_l(rh->bsec);
+	rh->align	= endian_s(rh->align);
+	rh->bits	= endian_s(rh->bits);
+	rh->datasize	= endian_l(rh->datasize);
+
 	return sizeof(struct riff_header);
 }
 
@@ -68,6 +81,7 @@
 
 	gsm_frame s;
 	gsm_byte *p;
+	gsm_signal *w;	/* used to step through output for endianness */
 	int i;
 
 	p = (gsm_byte *)vmo_frame;
@@ -84,7 +98,12 @@
 		/* invalid frame */
 		bzero(buffer, 160 * sizeof(gsm_signal));
 	}
-	
+	else {
+		/* valid frame, but how about endianness? */
+		for (w = (gsm_signal *) buffer, i=160; (i-- > 0); ++w) {
+			*w = endian_s(*w);
+		}
+	}
 	return;
 }
 
@@ -94,3 +113,45 @@
 
 }
 
+/* These two routines convert shorts (16 bits) and
+ * longs (32 bits) to little endian format. Trick is to let the
+ * compiler store a multibyte number in endian_test. On a little
+ * endian machine, this will result in the LSB being 1 whereas
+ * on a big endian machine it will be 0. By casting a pointer
+ * to unsigned char, we can determine the endianness automagically.
+ * If we discover we are running on a big endian, we swap, otherwise
+ * we do nothing.
+ */
+
+short endian_s(short i) {
+  static short endian_test = 0x0001;
+  unsigned char *little_endian = (unsigned char *) &endian_test;
+  unsigned char b0,b1;
+
+  if (*little_endian) {
+    return i;
+  }
+  else {
+    b0 = (i & 0x00FF);
+    b1 = ((i & 0xFF00) >> 8);
+    return (b0 << 8) |  b1;
+  }
+}
+
+long endian_l(long i) {
+  static short endian_test = 0x0001;
+  unsigned char *little_endian = (unsigned char *) &endian_test;
+  unsigned char b0,b1,b2,b3;
+
+  if (*little_endian) {
+    return i;
+  }
+  else {
+    b0 = (i & 0x000000FF);
+    b1 = ((i & 0x0000FF00) >> 8);
+    b2 = ((i & 0x00FF0000) >> 16);
+    b3 = ((i & 0xFF000000) >> 24);
+    return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
+  }
+}
+

Patches voor vmconvert.h

--- vmconvert.h-orig	2005-08-03 13:14:36.000000000 +0200
+++ vmconvert.h	2005-08-03 09:40:04.000000000 +0200
@@ -1,3 +1,5 @@
+/* vmconvert.h - adapted by Peter Fokker <peter@berestijn.nl> ; deal with endianness  2005-08-03 */
+
 #ifndef VMCONVERT_H
 #define VMCONVERT_H
 
@@ -5,6 +7,8 @@
 int vmo_start();
 void vmo_decode(void *vmo_frame, void *buffer);
 void vmo_end();
+short endian_s(short i);
+long endian_l(long i);
 
 #endif


Author: Peter Fokker <peter (at) berestijn (dot) nl>