Friday, October 16, 2009

My Latest Work

Well, I've been really caught up with my day job. So I've had no time to continue my Android VoIP experimentation, but I will try to complete a working prototype the moment I get a little slack from my job. So till the next post...

Thursday, July 23, 2009

Writing applications using the Android NDK

I did not find any easy to read tutorials on how to exactly build an Android app with some native code component. Its true that the NDK package comes with some docs, but for Android beginners, this may not be an exciting prospect. However, I still maintain that the docs in the package are a must-read.

The following app simply prints out a small string returned from a C function on the LogView.

1. Create a Normal Android app. Lets call it 'native1'.
2. The main source file should look like this.


package com.earl.native1;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class native1 extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Log.i("--EARL--", new NativeLib().getHelloWorld());
}
}

class NativeLib
{
public native String getHelloWorld();

static {
System.loadLibrary("helloworld");
}

}



3. If you are using Eclipse, the class files built will be in the 'bin' directory.
4. Navigate to it and run 'javah' on the class file that contains the native method.

javah -jni com.earl.native1.NativeLib

5. After this, you will get one header file. This file contains the JNIEXPORTs generated from the java source.
6. Copy this file and paste it in a folder in the 'sources' dir of the Android NDK. I'm calling the folder 'earl'.
7. Now, create the C implementation file - earl.c It should look like this.


#include "com_earl_native1_NativeLib.h"

JNIEXPORT jstring JNICALL Java_com_earl_native1_NativeLib_getHelloWorld
(JNIEnv * env, jobject obj)
{
return (*env)->NewStringUTF(env, "Greetings from Earlence !");
}



8. Now you have to create the Android.mk file. This file describes your native code module to the build system. This file is created in the same dir as the source file.



# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := earl.c

include $(BUILD_SHARED_LIBRARY)




9. Now, navigate to the 'apps' dir in the NDK home and create a folder of your choice. This will hold the Android Application you built using Eclipse earlier. I am calling it earl_jni. In this folder, create another one and call it 'projects'. In this, copy your ENTIRE eclipse project 'native1'. Then, navigate one level up to earl_jni and create the Application.mk file.



APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := helloworld



10. Now, navigate to the NDK home and run the make command.

$ make APP=earl_jni

11. You should see this output if everything works correctly.


Android NDK: Building for application 'earl_jni'
Compile thumb : helloworld <= sources/earl/earl.c
SharedLibrary :
libhelloworld.so
Install : libhelloworld.so => apps/earl_jni/project/libs/armeabi


12. Now, a folder called 'libs' will be created in apps/earl_jni/projects. This contains the .so file i.e the native library. Copy this into the eclipse project root. Compile and run. You should see something like on the LogView


I/ActivityManager( 564): Starting activity: Intent { action=android.intent.acti
on.MAIN categories={android.intent.category.LAUNCHER} flags=0x10200000 comp={com
.earl.native1/com.earl.native1.native1} }
I/--EARL--( 699): Greetings from Earlence !
I/ActivityManager( 564): Displayed activity com.earl.native1/.native1: 704 ms


Congratulations!!! You have just built your first JNI app for Android.





Installing Android NDK on Windows XP/Vista

What you need:

  • A Windows XP/Vista computer (yeah, u absolutely need it :)).
  • cygwin (make sure that make and gcc utilities are installed).
  • Android SDK 1.5
Steps to install:

  • Download the NDK from the Android developer site and unpack it to a disk location. I'm calling this NDK_HOME.
  • Startup cygwin and navigate to NDK_HOME.
  • Enter this command
  • export ANDROID_NDK_ROOT=NDK_HOME (note, use forward slashes '/' instead of the usual windows backslash. Remember that you are using a Linux emulation tool!).
  • Run this setup command.
  • bash build/host-setup.sh
  • You should get a "Host Setup Complete" message if everything went properly.
You're done.

Tuesday, July 21, 2009

NAT Traversal for Android

STUN (Simple Traversal of User Datagram Protocol through Network Address Translators) is a protocol that helps in the traversal of NATs/Firewalls. STUN works with full cone NAT, restricted cone NAT, and port restricted cone NAT. It does not work with Symmetric NATs. Traversal Using Relay NAT(TURN) maybe used in these cases. Another method for traversal is ICE (Interactive Connectivity Establishment). Here, I am focusing on NAT traversal for Android phones using STUN

  • jStun
  • stun4j
These are two STUN libraries available for the Java language. A jStun port is available from HSC. I've tested this on the Android Emulator. It returns an IP address and port mapping.

stun4j is another STUN library. This I tried directly on the Android emulator with no porting. It works directly with no code changes. I have compared results from both the libraries. Results are the same!!!


Monday, July 20, 2009

Real Time Audio Streaming for Android - Some Developments

OK, so I've made some progress on this project.

  • I have figured out how the Audio Streaming APIs work on the 1.5 SDK.
  • I have obtained a G 711 speech codec in Java which runs on Android. This was taken from the 'sipdroid' VoIP client.
  • I have been able to stream a pre-recorded PCM voice file to the emulator via UDP and play it using AudioTrack.
  • I have figured out how to use the jLibRtp RTP stack in a Java program. There is a port of the same stack by HSC for Android. So I guess it should work there also, but, I must still test it out.
So, it looks like most of the pieces of the puzzle are in place. However, while using AudioRecord and UDP on the emulator, I have encountered the following problems.

  1. On the emulator, I instantiate AudioRecord with a sampling rate of 8000Hz and an encoding of 16BIT PCM. This works fine. However, when I try to run the same code on a device, the AudioRecord object does not get created. Looks like I will have to experiment with different sampling rates and buffer sizes. Strange, huh?
  2. To test the sending and receiving of PCM data, I built a small Java applet that streamed the PCM data to the emulator. I setup proper port redirections. I am able to receive the data in the emulator, but, when I try to send data OUT from the emulator, nothing happens.
Looks like once these problems are sorted out, we are good to go!!!


Thursday, June 11, 2009

Real Time Voice Streaming for Google Android - Part 2 [Technical Details]

To stream voice, fundamentally, we need the following components.
  • A method to obtain PCM audio from the Mic and store it in an in-memory buffer.
  • A protocol suitable for transfer of real time data - RTP in other words.
  • Some kind of signaling protocol to negotiate the call. (Eg: SIP, XMPP/Jingle).
  • A codec to optimize the data transfer format. (Eg: Speex).
As far as the Google Android platform is considered, until recently (Android SDK 1.1 and lower) did not have the first capability. Android 1.5 still does not have an RTP stack, but I have ported a small but functional Open Source RTP stack to the platform. As for signalling, SIP and XMPP/Jingle, I feel have too much overhead. Since both peers will be utilizing my client, a stripped down negotiation protocol would be more efficient. This is where XMPP comes in. As you may know, XMPP is XML based and is widely used. Hence, we can build a small but fast call negotiation protocol over XMPP, given that the parties are logged in via their Jabber accounts.
One may think that this won't inter-operate with existing infrastructures. This is true. To have that capability would translate into unnecessary complexity at this stage. Integration with existing systems is future work as of now. :-)



Another point is that trasmitting raw PCM over the internet is not a very efficient design choice. For this, we need some kind of Codec that will provide us with compression, decompression etc. the Speex codec is Open source and available in Java as jSpeex. It is simple to use.




I will be approaching this project in the following manner.

1. Write PURE java code and test my ideas and algorithms on a Java applet.
2. Port it to the Android platform.


Real Time Voice Streaming for Google Android - Part 1 [Intro]

Your first thought might be, "Hey, isn't that already available with Skype?". Well, yes and no. For starters, to use the Skype services, ALL features may not be free depending on whom you contact. Secondly, you need to create a specialized Skype account to use their services. What I intend on doing is to utilize existing Google Mail and Jabber IDs to build a P2P voice streaming application for the Android platform(and maybe others, but for now, lets narrow it down). You don't have to create a special ID to use the service. Just login via your already existing GMail or Jabber IDs and start talking!!!

Tuesday, April 28, 2009

My Latest Endeavors

Hey There, been a long time indeed.....


I thought that I would post my latest R&D work here. So here goes.


  • Android 1.5 is out - Hence, try out streaming and therefore VoIP.
  • MorseXMPP.
  • Distributed AI in general and for Web Searches.
  • Installation of MAC OS X on x86 machines.
If anyone's interested in any of these topics, drop me a mail!!!

Cheers!!!

Friday, January 16, 2009

How to program in C :-)

Read on...

1. Use lots of global variables.
2. Give them cryptic names such as: X27, a_gcl, or Horace.
3. Put everything in one large .h file.
4. Implement the entire project at once.
5. Use macros and #defines to emulate Pascal.
6. Assume the compiler takes care of all the little details you didn't quite understand.
7. Rewrite standard functions and give them your own obscure names.
8. Use obscure, proprietary, non-portable, compiled library packages so that you never have to move from the platform you love so well.
9. Use very descriptive comments like /* printf("Hello world\n"); */ before each function call.
10. REMEMBER - Carriage returns are for weenies. Tabs are for those who have not reached weenie-dom yet.
11. Include LOTS of inline assembly code.
12. "User Interfaces" are for morons. "Users" have no business interfacing with a professional product like yours.
13. If you are forced to comment your code (in English), then borrow comments from somebody else's code and sprinkle them throughout yours. It's quick, easy, and fun to watch people's expressions as they try to figure it out.
14. Remember to define as many pre-processor symbols as possible in terms of already defined symbols. This is considered 'efficient use of code'.

How to debug in C :-) :-)

After reading this, I'm sure you won't ever have problems debugging again!!!!

1. If at all possible, don't. Let someone else do it.
2. Change majors.
3. Insert/remove blank lines at random spots, re-compile, and execute.
4. Throw holy water on the terminal.
5. Dial 911 and scream.
6. There is rumor that "printf" is useful, but this is probably unfounded.
7. Port everything to CP/M.
8. If it still doesn't work, re-write it in assembler. This won't fix the bug, but it will make sure no one else finds it and makes you look bad.
9. Since you got it to compile, the problem must be in the Other Guys Code.
10. If it's all your code then the problem MUST be in those unreliable Standard Libraries. See '1'.
11. Claim the bug reports are vicious lies meant to tarnish your sterling reputation as a 'C' programmer (well aren't they ?). After all, those who wrote the reports couldn't even read your code. How could they possibly know if there was a bug or not?
12. If they could read your code, review "How to program in C", above.
13. Claim that there wouldn't be a problem if this stingy Company/School/Wife/etc would spring for a copy of C++.

Saturday, January 10, 2009

Bob: Hello, Pete: Aloha, Bob: Whats up dude?...

Tutorial: Creating your own Grade-I VoIP network so that you can Voice Chat with your buddies. [Part I]



What you need:
1. A computer (obviously!).
2. A softphone application (I suggest X-Lite, just go to www.google.com and search for X-Lite download).
3. A Soft-PBX (go to http://www.freeswitch.org and download).
4. A DNS name for your system (go to http://www.dyndns.org and register for a free account).



The 'Low-Down' on Voice Chatting:



I will explain the basics here because I feel that if you have a little background on the subject, it would be much more easier to have your voice chatting service up and running.
Okay, so here goes....



  • To voice chat with your buddies, you must have a way of identifying them independently of their IP and port address combination. This is where a server comes in. Basically, all your buddies register on the server. They obtain identifers of the form 'user@domain'. (We will be using FreeSwitch, also known as FS). Note that the 'user' part is an extension number. You use this when you dial a friend.
  • The server functions as a 'registrar', meaning that people register here, and it stores a database mapping the users current IP and port to the identifier.
  • Once all your buddies are registered on the server, they must use a 'Softphone' application. This is software that can make and recieve VoIP calls. Technically, it is known as a SIP UA.
  • To make a call to a friend, all you have to do is dial his extension and Hey Presto!!!, you are calling your friend.


I must admit, this was a very 'Non-Technical' introduction, but you don't need ALL the details to do it practically. Nevertheless, I will write a post highlighting the technical details.



Well, so much for this post. I will write the exact process in a later post. This series is going to be quite a long one, so, till then...

Sunday, January 4, 2009

Java for the iPhone (without jailbreaking)

I bet you must be thinking, "What???, How is this is possible." I too was thinking the exact same thing when I came across this project. Running Java on the iPhone, or rather, building apps for the iPhone using Java is part of a larger project known as XMLVM (http://www.xmlvm.org) that utilizes XML as an intermediate language for cross-compiling at the byte-code level. Note that this cross-compilation is NOT at the source level. XMLVM cross-compiles byte code instructions from Sun Microsystem's virtual machine and Microsoft's Common Language Runtime. XMLVM can be used to cross compile .NET CIL, Ruby YARV and Java Byte Code to JavaScript, Python and Objective-C/C++


Details on Java for iPhone:
XMLVM operation begins with the byte code outputted from a regular Java compiler. Then, an XML version of the byte code is produced. This is then transformed into Objective-C using transformations on the original XML with the help of XSLT. What results is the same, functionally equivalent code in Objective-C. This can then be linked with libraries for UI (Cocoa) etc. to produce a native iPhone app.


XMLVM goes one step further. They have implemented Java counterparts of the Cocoa library components. This makes it possible to develop apps for the iPhone on Windows. The XMLVM project offers an iPhone emulator which is actually a Java Applet.


Example of the classic Hello, World app for the iPhone using Java:


public class HelloWorld extends UIApplication
{
public void applicationDidFinishLaunching(NSNotification aNotification)
{
CGRect rect = UIHardware.fullScreenApplicationContentRect();
UIWindow window =
new UIWindow(rect);
window.orderFront
(this);
window.makeKey
(this);
window._setHidden
(false);
rect.origin.x = rect.origin.y =
0;
UIView mainView =
new UIView(rect);
window.setContentView
(mainView);
UITextLabel _title =
new UITextLabel(rect);
_title.setText
("Hello World!, This is Earlence");
_title.setCentersHorizontally
(true);
mainView.addSubview
(_title);
}

public static void main(String[] args)
{
UIApplication.main(args, HelloWorld.class);
}
}


(adapted from XMLVM project site)

As you can see, development for the iPhone just got a little easier.

Friday, January 2, 2009

Programming, Programming, Programming...

Aah!, The word has a merry ring to it!, but alas, not all people think alike!!!. I would like to share a few thoughts of mine about programming in this post.


We have all heard the phrase "Programming is an Art and not a Science". I, for one, feel that it should be "Programming is an Art and not a Science, BUT it becomes a Craft with experience". It is very true that when one starts out initially, everything is a challenge, and hence programming is perceived as an Art, but this is only half the picture. As a person gains experience, he gains the mental facility to express his ideas in a programming language with ease. Hence, programming becomes a craft.


If you are a keen reader, you would have noticed something about the previous paragraph. I gave some insight into what separates average programmers from the so called "Virtuosos". They very fact that I used the word "Craft" and "Experience" says that excellent programmers mostly aren't born with the ability, instead, their skill is a result of a lot of hard work. I can give an example here. It is a common fact that a person can learn to play the Guitar to any skill level he/she desires. The only catch here, is practice, and practice translates into experience. The same is true for programming. I've been wanting to avoid the cliche, "Practice makes Perfect", but please, do not be mistaken, these words are very true indeed!!!


So, you might be thinking, "Cool!, so What can I do to improve my skills?". Well, I have a few pointers that I found very helpful when I was starting out.


  • Don't think of programming as a burden, think of it as a recreational activity.
  • Pick a language you are comfortable with. Note that this post isn't about learning a language. I feel anyone can learn a language. Its how you translate your ideas into the language. Logic matters!!!
  • Start off by solving relatively easy problems. Don't pick anything too hard.
  • Remember how you solved earlier problems. You should be comfortable with the idea of resuing the ideas you used to solve earlier problems. With time, one almost gets a feeling of deja-vu "Hey, I think i've done this before!!". This will greatly help your abilities related to intergration of solutions.
  • Try to read the book, "Structure and Interpretation of Computer Programs", by Alan J. Perlis.
  • If you choose to program in C initially, read the book by Kernighan and Ritchie and the book "Programming in C" by Venugopal Prasad.
  • Listen to music while you program!!!. Well, I don't know whether this will be helpful to everyone, but it sure as hell helps me out.

Well, I would like to end this post by saying that it doesn't matter how many languages you know. What matters is whether you are able to express your ideas in the language effectively and Nothing Else Matters!!!


"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."
--Brian Kernighan





The First Post

Well, guess what??? This is my first post!!! I bet you couldn't figure that one out, eh? :) Just Kiddin'!!!!


This blog is my resolution for the year 2009. This is a place where I write about my passions in life, namely, Computer Technology, Guitars and Rock Music.


I use the word Computer Technology because I focus on a wide array of fields ranging from Artificial Intelligence to Systems Programming. (well, I wanted it to be an A to Z, but I couldn't find anything with a Z!!!)


Anyway, I hope you enjoy reading my blog and for all the "Tech Geeks" out there, hope you have a blast reading this blog.


Cheers,
Earlence Tezroyd Fernandes