Thursday, March 22, 2012

C/C++ : Combination (n,k)

This below code show how to print out all cases for C(n,k):

#include stdio.h
#include conio.h
void print(int a[],int n)
{
for(int i=0;i
printf("%4d",a[i]);
printf("\n");
}
void combine(int a[],int n, int k, int i)
{
for(int j=0;j<=n-k+i+1;j++)
{
a[i]=j;
if(i==k-1)
print(a,k);
else
combine(a,n,k,i+1);
}
}
int main()
{
int a[100],n,k;
printf("N: ");
scanf("%d",&n);
printf("K: ");
scanf("%d",&k);
a[0]=0;
combine(a,n,k,0);
getch();
return 0;
}

Tuesday, March 20, 2012

How to build ISO android-x86 in Ubuntu

Follow these below steps to build ISO android-x86 (generic_x86):

I. Prepare your Ubuntu system:
1. Intall JDK
A. Additional repository
i. $ sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ jaunty multiverse"
ii. $ sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse"
B. $ sudo apt-get update
i. if you failed update, fallowing next step.
1. $ sudo vim /etc/apt/sources.list
 Add the following lines in the end of source.list
deb http://old-releases.ubuntu.com/ubuntu/ jaunty-updates multiverse
2. sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
3. sudo apt-get update
C. $ sudo apt-get install sun-java6-jdk
D. if this is success, you can see some message. Input that commands.
i. $ javac -version
ii. $ java –version
E. $ sudo vim /etc/profile
 Add the following lines in the end of profile:
JAVA_HOME=/usr/bin/java
ANDROID_JAVA_HOME=$JAVA_HOME
PATH=$PATH :$JAVA_HOME/bin:~/bin:
--> save (wq)
v. $ source /etc/profile
F. $ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev libncurses5-dev x11proto-core-dev libx11-dev libreadline6-dev libgl1-mesa-dev g++-multilib tofrodos python-markdown libxml2-utils xsltproc
G. Install repo
i. $ cd ~
ii. $ mkdir bin
iv. $ chmod a+x ~/bin/repo
II. Download Android resource
i. $ cd ~
ii. $ mkdir android_src
iii. $ cd android_src
iv. $ repo init -u https://android.googlesource.com/platform/manifest -b gingerbread
v. $ repo sync ß This takes long time

III. Build ISO file:
Go to folder resource:
$sudo make iso_img TARGET_PRODUCT=generic_x86

Well, go to the coffee shop and wait for around 5hours...
Ok, now we got the ISO file ....

Linux C++ : Append int to char*

int count = 1;
char name[10] = "out";
char num[2];

sprintf(num, "%d",count); //int -> char
strcat(name,num); //out1

A Method to Capture Android-x86 System Audio

(From BY: XZPETER - 20TH, 2011 )

I have just posted a note about a month ago about video capturing in android system (that post is written in Chinese). This time I will talk something about audio capture.

Actually, I have looking into the issue for some days, and I didn’t find a good way to do that. There are indeed some articles talked about different ways to do audio recording in android by all kinds of APIs, like OpenSLES (this should be supported after gingerbread) orMediaRecorder which belongs to android SDK API. However nearly all of them were recording the mic input, rather than the system output. Meanwhile, I have seen many posts on android-dev asking for the same question, and it seems that there is currently no valid answer on this. So I hope my method will at least make some sense for those whoreally want to capture the system output and don’t know how, like me.

My method is not good, since you have to recompile the android tree, however this is currently the only way for me to achieve my goal. Please tell me if you know other ways to do that. So download the android source tree will be the first step here. And the main idea of the work is: since there is no API for system audio capture, we have to capture it by ourselves, in a lower level, e.g., the android framework.

The source.android.com is the best place for you if you don’t have a android source tree, andUbuntu is highly suggested as the compiling environment. After you have read that, you should have a workable android source tree. here workable means you should be able to compile the tree and launch emulator successfully with the android kernel you just compiled. To achieve that, you may have to establish the environment first (e.g. to installsun-java-6, not the one called openjdk, which may cause strange compilation errors), run some scripts to initialize macros for compilation (like source build/envsetup.sh andlunch), and finally run make -j8 under your android source root. (if you don’t use -j8, which means enable parallel compilation with eight threads, you will possibly have to wait for a really long time before the compilation is done)

1. Play some audio

Before we try to capture the system sound, we do have to find some audio to play, so that we can know we have captured something. This is really a easy task. Just find any mp3 file (e.g. music.mp3), put it under the android /sdcard/ dir with adb push (CAUTION here: you have to use mksdcard command to create a sdcard image, and then use -sdcard option when launching the emulator. By default, the emulator will have no sdcard mounted).

Then, use the Media Scanner of dev tools in the android system to activate the scan process of audio files. After that, in the application called Music there should be a mp3 file ready for you to play. By playing the song, You should be able to hear the sound on your host, although it is actually played on the emulator.

2. Do the system audio capture

Comes to the main part of this article. first of all let’s see the android audio system in the graph.

Android Audio System

I am not a expert on android system, but we can see here that the lowest level of audio system goes to /dev/eac device file, and there is an AudioHardwareInterface, which is possibly hardware related, to access this file directly. And here AudioFlinger seems to be the best part for us to hack, since it is not depending on hardware, and it should has the final mixer output, which is what we want (we don’t want any single sound track, we need the overall system output, isn’t it?). Actually, here AudioFlinger did not only the mixer work, and also resampling stuff.

AudioFlinger is implemented under dir frameworks/base/services/audioflinger/ (Here I assume that we are currently under the root of android source tree). What we are going to do is to find the mixer output. In the file AudioFlinger.cpp, we can seeAudioFlinger::MixerThread::threadLoop(), which is the working thread of the mixer, and this MixerThread is inherited from AudioFlinger::BaseThread. Then, just search the keyword mOutput->write with your best editor (vim, emacs, gedit, whatever), and we will find something like this under the threadLoop() function:

...
mLastWriteTime = systemTime();
mInWrite = true;
mBytesWritten += mixBufferSize;
int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
...

That is the very point that mixer output buffer is transferred to hardware related codes I think, and the audio clip is in mMixbuffer, with size mixBufferSize. In this buffer, there are PCM raw audio data with 44100Hz sampling rate, 2 channels and 16 bits little endian as its param.

If you write this buffer out to a file, like /data/wav.raw, you can just use adb pull to retrieve the data file to your host machine and play it with aplay:

$ aplay -t raw -c 2 -f S16_LE -r 44100 wav.raw

Didn’t you heard the sound? That’s it.

Monday, March 19, 2012

Linux: Simple Socket Server in C++

#define _REENTRANT
#include stdio.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include string.h
#include sys/uio.h
#include unistd.h

/* the TCP port that is used for this example */
#define TCP_PORT 6000

main()
{
int sockfd, newsockfd, clilen;
struct sockaddr_in cli_addr, serv_addr;
//thread_t chld_thr;

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
fprintf(stderr,"server: can't open stream socket\n");
return 0;
}

memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
//Use INADDR_ANY instead of IP here
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(TCP_PORT);
printf("This is Socket Server...\n");
printf("%c", serv_addr.sin_addr.s_addr);

if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
fprintf(stderr,"server: can't bind local address\n"); return 0;}

listen(sockfd, 5);

for(;;){
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);

if(newsockfd < 0){
fprintf(stderr,"server: accept error\n"); return 0;}

printf("Connected to Client...\n");
/* the server is now free to accept another socket request */
}
return(0);
}