Friday, June 29, 2007

Au - rendering (cscope with helix code)

- start from the decoding function (PCM_CONVERTER_ULaw2Linear)
use cscope, I can find who call it, or it call whom.
Here I focus on the first part, who call it?

- it was CPCMAudioFormat::DecodeAudioData
go to definition

- CPCMAudioFormat is derected by CAudioFormat
so what is CAudioFormat?

- CAudioFormat is a fileformat reader, there is no "I" class related to it.
now go back to find who use CPCMAudioFormat? C-F5

- it was in datatype/wav/renderer/pcm/pcmrend.cpp
class CPCMAudioRenderer, function CreateFormatObject.
so take me to CPCMAudioRenderer(C-F7)

- datatype/wav/renderer/pcm/pub/pcmrend.h
take a close look on CPCMAudioRender
1 is it a plugin? Sure it is, GetPluginInfo will return the plugin information.

- take a look on IHXPlugin, it has two functions, GetPlugInfo, and InitPlugIn
so where is InitPlugin for CPCMAudioRender?

- IT is strange it does not have InitPlugin. !!!
Now take a look on IHXRenderer.

- Actually I take a look of CAudioRenderer, it is public directed from IHXPlugin and IHXRenderer
- it has a InitPlugin, that's why CPCMAudioRenderer does not contained it.


- It is easy to use definition of CAudioRenderer to find the implementation of InitPlugin.
Now goback to CAudioRenderer, to find what kind of function should be defined as a renderer.

- hxrendr.h GetRendererInfo, StartStream,EndStream OnHeader, OnPacket OnTimeSync etc.
so goto CPCMAudioRenderer or CAudioRenderer to find each implentation

- It is good CAudioRenderer contains a bunch of implementation such as
StartStream, EndStream etc.
So for PCM renderer, what should be implemented?

- As i read in CPCMAudioRenderer, GetRendererInfo it contains "const string" for the class.(information). CreateFormatObject to create CPCMAudioFormat
HXCreetaeInstance to create its self, and CanUpload2 (I think this one is not important)
so the main thing is what I read before "CreateFormatObject"!

- Read "SDK::coding a rendering plugin for audio", it is a little different
a. StartStream, get interface of AudioPlayer.
YES CAudioRenderer::StartStream contains it.
b. Create an AudioStream object, is it not in StartStream?
Let me find CreateAudioStream, it is in CAudioRenderer::InitAudioStream
c. InitAudioStream was call in CAudioRenderer::OnHeader, OnHeader first create format object, then create audio stream object.
d. As I read the SDK, OnHeader required channels, bits per sampel, samples per sec etc, where is it in the code?
Hey, That's HXAudioFormat, how it is set?
e. m_pAudioFormat (in CAudioRenderer) is created by CreateFormatObject, I
seems wandering here :-) Just take anothe close look on CreateFormatObject.
f. So I goback to CAudioFormat::GetAudioForamt, the convertion of
HXAudioFormat
Here is the result:


HX_RESULT CAudioFormat::GetAudioFormat(HXAudioFormat& audioFmt)
{
audioFmt.uChannels = m_pAudioFmt->uChannels;
audioFmt.uBitsPerSample = m_pAudioFmt->uBitsPerSample;
audioFmt.ulSamplesPerSec = m_pAudioFmt->ulSamplesPerSec;
audioFmt.uMaxBlockSize = m_pAudioFmt->uMaxBlockSize;

return HXR_OK;
}

the up questions are figured out.

g. (the 4th on page 175) m_pAudioStream::Init with pHeader at audrend.cpp.
What is pHeader.


- Now let's go back, another question who call DecodeAudioData in
CPCMAudioFormat? (Before this question, I have digged about the creation
CPMCAudioFormat.

a It is at CAudioFormat::CreateAudioFrame, so who call this function?

b The answer is CAudioRenderer::DoAudio, up??

c Now it is here: CAudioRenderer::OnPacket

d Now I found I am digging about the 5th on page 175

- Now is the write PCM audio data, (the 6th on page 175)
a. the write was called in CAudioRenderer::WriteToAudioServices
b. CAudioRenderer::DoAudio first CreateAudioFrame, then WriteToAudioServices.
(Note here there could be multiple audio stream)


== postmortem

1. with SDK's guideline, I can use cscope to find how it was implemented in
helix source code. so cscope is a very power tool!

2. use cscope on this things: (function example)
- where is the definition of the function (here)
- who call this function (up)
- In this function, it call what functions (below)
In C++, it is a little different, usually I check the definition of the
class, it will display member functions in this class, so I can locate the
function definition

%%% csope %%%
Finding functions calling: WriteToAudioServices

Database directory: /home/build/src/cscope_d/
-------------------------------------------------------------------------------
*** /home/build/src/helix/datatype/common/audrend/audrend.cpp:
DoAudio[1401] retVal = WriteToAudioServices(&audioData);

*** /home/build/src/helix/datatype/rm/audio/renderer/rarender.cpp:
DoAudio[1688] pnr = WriteToAudioServices(uLowest, &audioData, ulActualTimestamp);

%%%%%%%%%%%%%%%5

move curser to DoAudio, type 'c', it will find functions that call DoAudio.

- right now, the problem is how to go back to WriteToAudioServerices, I need
to buffer list, or go back to class, then locate the source code to find
it, it is seems no covenient.

3. main issue: use gdb how to debug it? (the renderering plugin)

Au - the basic

Check here for the basic concept of Au. Au is quite simple audio format, it is just PCM data with compression. Below is a sound (Au format) I got for a fvwm effect sound:


00000000: 2e73 6e64 0000 0028 0000 02cf 0000 0001 .snd...(........
00000010: 0000 1f40 0000 0001 6f6e 6520 6472 6970 ...@....one drip
00000020: 0000 0000 0000 0000 fefe fffe fdff fefe ................
00000030: 7e7e 7c7d 7e7e 7eff 7e7e fe7f 7efe fefe ~~|}~~~.~~..~...
00000040: fefd fdff 7ffa e4e1 5846 4556 c0ad aab0 ........XFEV....
00000050: dc30 211c 1c22 37bb a096 8f8e 9198 aa2d .0!.."7........-
00000060: 170d 0909 0d11 1bd0 9d90 8a89 8b92 a732 ...............2
00000070: 190e 0c0d 1320 ee9f 918c 8b8d 97b9 2413 ..... ........$.
00000080: 0c0c 0e17 2daf 988e 8b8d 95af 2915 0d0c ....-.......)...
00000090: 0e19 34aa 958d 8c8f 9ce9 1d10 0d0e 1427 ..4............'
000000a0: b999 8e8c 8e9b ce1f 110d 0e17 2cae 968e ............,...
000000b0: 8d92 a438 180f 0e12 1fd6 9c8f 8d90 9e4d ...8...........M
000000c0: 1b10 0e13 20ce 9c8f 8e93 a634 180f 0f17 .... ......4....
000000d0: 2eac 968e 8f9b d61e 120f 1525 b999 8f90 ...........%....
000000e0: 9bca 1f13 1017 2ab1 9890 929f 461c 1213 ......*.....F...
000000f0: 1c47 a194 9199 bb25 1613 1931 aa96 9298 .G.....%...1....
00000100: b129 1814 1a32 aa97 939b bd25 1715 1e4d .)...2.....%...M
00000110: a195 96a2 451d 1619 2bb2 9a95 9cc4 2418 ....E...+.....$.
00000120: 1825 c39d 969c ba28 1919 26c3 9d98 9dc4 .%.....(..&.....
00000130: 261a 1b2d b49c 99a4 4c1f 1a1f 4aa6 9a9d &..-....L...J...
00000140: b92b 1c1d 2fb2 9d9c ac38 1e1d 2bbe 9f9c .+../....8..+...
00000150: aa3e 201d 2bbf a09d ad3a 201f 30b7 9f9f .> .+....: .0...
00000160: b82f 1f23 43ac 9fa7 f928 202d c5a4 a2b7 ./.#C....( -....
00000170: 3322 2750 aba2 ae44 2626 3eb1 a4ac 5729 3"'P...D&&>...W)
00000180: 273b b6a6 ac5b 2a28 3eb5 a7af 4b2a 2b4c ';...[*(>...K*+L
00000190: b0a9 b93c 2a2f d9ad acd0 322c 3ebb acb7 ...<*/....2,>...
000001a0: 462d 32df afaf e133 2f4d b7af c63b 2f40 F-2....3/M...;/@
000001b0: bfaf be42 313e c6b2 bd48 333e cab4 bf48 ...B1>...H3>...H
000001c0: 3541 c7b6 c544 374a c2b8 d13e 3a5d bdbc 5A...D7J...>:]..
000001d0: 7a3c 3fda bbc5 4c3c 4ec6 bde5 4041 e3bf z< ?...L< N...@A..
000001e0: c94e 3f59 c6c2 6f41 4bd2 c1dd 4747 e7c4 .N?Y..oAK...GG..
000001f0: d14e 4779 c7ce 5547 67cb ce59 4965 cccf .NGy..UGg..YIe..
00000200: 5b4b 6acd d25a 4d75 ced9 574f efcf e353 [Kj..ZMu..WO...S
00000210: 56e0 d1ff 525f d9d7 6454 7bd6 e45a 5ce2 V...R_..dT{..Z\.
00000220: d875 5871 dae3 5e5e e7db 745b 76dd ec5e .uXq..^^..t[v..^
00000230: 66e4 e268 5ff2 e178 5f7b e1f3 6370 e5ec f..h_..x_{..cp..
00000240: 676b ebec 6a69 efeb 6f6a f2ea 746b f2ea gk..ji..oj..tk..
00000250: 776d f6ee 706e f3ee 7570 f1ef 7574 f1f3 wm..pn..up..ut..
00000260: 7277 f3fb 6f79 f37c 72fd f37a 76f6 f878 rw..oy.|r..zv..x
00000270: 7bf8 7e75 7ffa 7b7a f9fa 797f f87e 7bfe {.~u..{z..y..~{.
00000280: fc7b 7dfb 7d78 fefd 7bfd f77e 7bfd fe7c .{}.}x..{..~{..|
00000290: 7efe 7b7f fd7e 7dfc fd7d fdfd 7d7e fd7c ~.{..~}..}..}~.|
000002a0: 7cfe 7d7d fffe 7efe fd7e fefe 7d7f 7e7e |.}}..~..~..}.~~
000002b0: 7e7e 7dfe fd7e ffff 7d7e fe7d 7e7f 7e7f ~~}..~..}~.}~.~.
000002c0: 7e7d ff7f fffe fc7f fffe ff7d 7c7a 7b7d ~}.........}|z{}
000002d0: 7d7f 7e7f fdfd fdfd fdff fefe 7e7d 7d7d }.~.........~}}}
000002e0: fffe ff7f ffff 7f7d 7e7f 7f7e 7e7e ff7f .......}~..~~~..
000002f0: fffe feff ffff 7e


The file was shown in emacs hex mode. Dig into it ---


header six 32-bit words
===================================
0 2e 73 63 64 magic numbers
1 00 00 00 28 data offset: 0x28 = 40
2 00 00 02 cf data size 0x2cf = 719 (0x2f6 = 758+1 (759))
3 00 00 00 01 encodeing mu-Law, damm! what's that?
4 00 00 1f 40 sample rate 8000
5 00 00 00 01 channels 1
=================================



mu-Law ??

basiccaly used in North America, Japan while A-Law(27) used in European and
the rest of the world.

The ยต-law and A-law algorithms encode 14-bit and 13-bit signed linear PCM
samples (respectively) to logarithmic 8-bit samples. Thus, the G.711
encoder will create a 64 kbit/s bitstream for a signal sampled at 8 kHz.

14/13 --> 8bit
8khz : 8000 samples per sec
-------------------------
so : 8*8000 = 64kbit/s per sec !!!

decoding algorithm:


const unsigned short g_wU2L16[] = {
33280, 34308, 35336, 36364, 37393, 38421, 39449, 40477,
41505, 42534, 43562, 44590, 45618, 46647, 47675, 48703,
49474, 49988, 50503, 51017, 51531, 52045, 52559, 53073,
53587, 54101, 54616, 55130, 55644, 56158, 56672, 57186,
57572, 57829, 58086, 58343, 58600, 58857, 59114, 59371,
59628, 59885, 60142, 60399, 60656, 60913, 61171, 61428,
61620, 61749, 61877, 62006, 62134, 62263, 62392, 62520,
62649, 62777, 62906, 63034, 63163, 63291, 63420, 63548,
63645, 63709, 63773, 63838, 63902, 63966, 64030, 64095,
64159, 64223, 64287, 64352, 64416, 64480, 64544, 64609,
64657, 64689, 64721, 64753, 64785, 64818, 64850, 64882,
64914, 64946, 64978, 65010, 65042, 65075, 65107, 65139,
65163, 65179, 65195, 65211, 65227, 65243, 65259, 65275,
65291, 65308, 65324, 65340, 65356, 65372, 65388, 65404,
65416, 65424, 65432, 65440, 65448, 65456, 65464, 65472,
65480, 65488, 65496, 65504, 65512, 65520, 65528, 0,
32256, 31228, 30200, 29172, 28143, 27115, 26087, 25059,
24031, 23002, 21974, 20946, 19918, 18889, 17861, 16833,
16062, 15548, 15033, 14519, 14005, 13491, 12977, 12463,
11949, 11435, 10920, 10406, 9892, 9378, 8864, 8350,
7964, 7707, 7450, 7193, 6936, 6679, 6422, 6165,
5908, 5651, 5394, 5137, 4880, 4623, 4365, 4108,
3916, 3787, 3659, 3530, 3402, 3273, 3144, 3016,
2887, 2759, 2630, 2502, 2373, 2245, 2116, 1988,
1891, 1827, 1763, 1698, 1634, 1570, 1506, 1441,
1377, 1313, 1249, 1184, 1120, 1056, 992, 927,
879, 847, 815, 783, 751, 718, 686, 654,
622, 590, 558, 526, 494, 461, 429, 397,
373, 357, 341, 325, 309, 293, 277, 261,
245, 228, 212, 196, 180, 164, 148, 132,
120, 112, 104, 96, 88, 80, 72, 64,
56, 48, 40, 32, 24, 16, 8, 0
};

// from 8bit to 16 bit (PCM data)
unsigned int
PCM_CONVERTER_ULaw2Linear(unsigned char* pbSrc,unsigned short* pwDest,
unsigned int dwSampleNum)
{
unsigned char* pSrcEnd;

HX_ASSERT(pbSrc && pwDest);

for(pSrcEnd=pbSrc+dwSampleNum; pbSrc < pSrcEnd; pbSrc++,pwDest++)
*pwDest = PCM_CONVERTER_U_TO_L16(*pbSrc);

return dwSampleNum;
}

emacs - new font

Today I found Eric Raymond's fvwm2rc file, and found he use fixed font on 15, it looks good on my computer, so I change my configuration of fvwm, I also disable titles of emacs and xterm, just hope xterm is ok to be put on the right side.
Here is another view with "-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso8859-1".

Thursday, June 28, 2007

fvwm - On fedora 5 VM machine


Fvwm is my choice of window manager on linux, it seems a little obsolete at today 21 century, but I love it's simple and fast.

Here is the way to install: first "yum install fvwm", that is definitely, but you also need this package -- switchdesk, using it will avoid all the manual change of the startup scripts. Use switchdesk is super easy -- "switchdesk fvwm".

The next thing is config the desktop, I use a package from here. It does not contains a lot of stuff, farely suit my development puperpose.

Right now, the problem using the built fvwm by Fedora is, it does not include the xft, so I can only use the basic font. Otherwise, everything should be ok.

For windows managers, usually fvwm is my first choice, I also choose sawfish (on gnome) before, it seems sawfish is not updated for 2 or 3 years, is it died? I don't know.

Tuesday, June 26, 2007

vmware - hostname is minint-xxxx

I am not quite familiar with VMWare, it seems always have problems. It is strange on my FC5, the host name sometimes shows minint-blahblah, I change the setting from bridge to NAT, and it starts to use the host name defined in /etc/hosts. (NAT is used to share host's IP address)

Monday, June 25, 2007

fetchmail -- by Eric S Raymond

Raymond has written a famous book TAUP "The Art of Unix Programming", I borrowed it from library several times, I liked to read it--.

Until today, I download the source code of fetchmail, (it is a C case study in TAUP). Interesting found that fetchmail is really written by Raymond, so I see why there are a lot of samples are from fetchmail, POP3, SMTP etc, in the book (TAUP). Fetchmail is written by C and it is so neat!! As I cscope into it, the struct as "method", "query", etc, I like such nice design. When read the code, I found some routines are very long, is it a pity? But at least the whole functions or interfaces are kept light! The hard part to me is I am not going to learn the protocols (POP3, SMTP, RFCs). It is not documented in a doxygen layout although it contains a doxygen config file. Discard such things, I still think fetchmail is very good sample on C, it is great because it is coded farely "light" in C, even it deals with different protocols (RFCs).

Here is a demo in "fetchmail.h":

struct method /* describe methods for protocol state machine */
{
const char *name; /* protocol name */
const char *service; /* service port (unencrypted) */
const char *sslservice; /* service port (SSL) */
flag tagged; /* if true, generate & expect command tags */
flag delimited; /* if true, accept "." message delimiter */
int (*parse_response)(int, char *);
/* response_parsing function */
int (*getauth)(int, struct query *, char *);
/* authorization fetcher */
int (*getrange)(int, struct query *, const char *, int *, int *, int *);
/* get message range to fetch */
int (*getsizes)(int, int, int *);
/* get sizes of messages */
int (*getpartialsizes)(int, int, int, int *);
/* get sizes of subset of messages */
int (*is_old)(int, struct query *, int);
/* check for old message */
int (*fetch_headers)(int, struct query *, int, int *);
/* fetch header from a given message */
int (*fetch_body)(int, struct query *, int, int *);
/* fetch a given message */
int (*trail)(int, struct query *, const char *);
/* eat trailer of a message */
int (*delete_msg)(int, struct query *, int);
/* delete method */
int (*mark_seen)(int, struct query *, int);
/* mark as seen method */
int (*end_mailbox_poll)(int, struct query *);
/* end-of-mailbox processing */
int (*logout_cmd)(int, struct query *);
/* logout command */
flag retry; /* can getrange poll for new messages? */
};

Friday, June 22, 2007

helix - build splay for playing wav files

Actually I am building splay with eshell, here is part of my configure scripts to support helix:


(defconst helix-build-root-dir "/home/build/src/build")
(defvar helix-eshell-initilized nil)
(defun helix-eshell-mode-hook ()
(when (not helix-eshell-initilized)
(setenv "BUILD_ROOT" helix-build-root-dir)
(setenv "SYSTEM_ID" "linux-2.2-libc6-gcc32-i586")
(setenv "CVS_RSH" "ssh")
(setenv "CVSROOT" ":ext:ifade@cvs.helixcommunity.org:/cvsroot/ribosome")
(ted-add-to-list* 'exec-path (expand-file-name "bin" helix-build-root-dir))
(setenv "PATH" (markc-build-path-string exec-path))
(setq helix-eshell t)))

(add-hook 'eshell-mode-hook 'helix-eshell-mode-hook)


Using it will save me a lot of time. Then is the build, I execute "build.py" on my eshell,
select:
branch: hxclient_2_0_3_cayenne (I think 1_5_0 do the same way)
profile :/home/build/src/build/umakepf/helix-client-all-defines
target(s): splay

Before run the build, I would like to check out source code first, that was the menu item 11.
[11] Checkout source for selected target now


then select "[3] run:build" to run the build.


til now, you can use splay play mp3, but not wav. what to do next?

still use "build.py" to build 2 "target"s, one is pcmrend.so, the other is audplin.so, I compared hxplay with splay, noticed that these two modules are missing.

Set Target(s) (datatype_wav_renderer_pcm)
and

Build Complete: Wed Jun 20 01:58:05 2007
MD5 (debug/pcmrend.so)................49444cb6dd56edc02fb640060d10a2b8
MD5 (debug/pcmrendlib.a)..............267039112af294a3f04ca7ec27126199
MD5 (debug/utillib.a).................e03cdbb51d2576d7172290befa3eaa1d


after the first target is done, still won't work, so I found the next:
Target(s) (datatype_group_audio)
and the result:

MD5 (debug/aiffplin.a)................54987e692a2cca90e03e5bf10107670c
MD5 (debug/amrdump)...................80a4c6179c913a6354f469ffaed1bc3e
MD5 (debug/amrff.so)..................7010c6ee2f3dffa8670091f22f5a1bec
MD5 (debug/audplin.so)................ec7b0fdf8766058d4c5cf1fadeb0f2eb
MD5 (debug/aufformat.so)..............5e037809b88e8285216d798f813464ba
MD5 (debug/auffplin.a)................cb8e007d0cba85fa0e87a82733d247ea
MD5 (debug/aviffpln.a)................68d0fafcd0c05f647f93fb6e0c86a11b
MD5 (debug/hxsdp.so)..................0df0191f0086ab4444e9c7e560989958
MD5 (debug/mp4arender.so).............3a4c5d3ad009eca23bae3c77a705d12a
MD5 (debug/pcmrend.so)................49444cb6dd56edc02fb640060d10a2b8
MD5 (debug/protutillib.a).............659b72f44b5f691cd3a24010413cfaab
MD5 (debug/rtsplib.a).................e82688da1e2305078911a606dcbe6a09
MD5 (debug/utillib.a).................f3eecdc4482d5ddd72529883bb396faf
MD5 (debug/wvffplin.a)................5583a00a7209d684642a65f1a4159ab9


Now I can play the wav...

/home/build/src/helix # ./debug/splay ~/Desktop/Heli44k.wav
Simpleplayer is looking for the client core at /home/build/src/helix/debug/clntcore.so
Common DLL path DT_Common=/home/build/src/helix/debug
Plugin path DT_Plugins=/home/build/src/helix/debug
Codec path DT_Codecs=/home/build/src/helix/debug
Can't open file: /root/.helix/HelixShared_0_0.
opening file:///root/Desktop/Heli44k.wav on player 0
Device Configured:
Sample Rate: 44100
Sample Width: 16
Num channels: 1
Block size: 4400
Device buffer size: 65536
Supports GETOSPACE: 1
Supports GETODELAY: 0
----------------clip info--------------------
========Source 0========
====File Header====
StreamCount 1
Flags 1
====Stream 0====
StreamNumber 0
MaxBitRate 705600
AvgBitRate 705600
MaxPacketSize 1764
AvgPacketSize 1764
StartTime 0
Preroll 2000
Duration 11998
BitsPerSample 16
SamplesPerSecond 44100
Channels 1
RTPPayloadType 11
TrackEndTime 11998
PostDecodeDelay 3000
MimeType audio/L16
---------------------------------------------
q
q
/home/build/src/helix #