Archive

Archive for the ‘Linux’ Category

Back in the Dutch Ubuntu LoCoTeam

August 20th, 2009 Wesley 2 comments

Back In 2006 I was active for nearly two years in the Dutch Ubuntu LoCoTeam as site/forum administrator and release party organiser. Due to time constraints (among many other factors) my participation as LoCoTeam member steadily declined. But yesterday I became moderator of the official Dutch Ubuntu forums again. So far the community response (by e-mail) has been wonderful. It feels kind of good to know that a lot of people thought you did a great job back then and that they are happy with your return :)

I hope I can make enough time to actively help out the LoCoTeam – because there’s a lot of other stuff to do as well – and I can only do my best. The reason for my renewed participation is that I want to make a difference instead of complaining about some of the problems I was seeing. Of course some problems are to be expected: Ubuntu-NL has grown considerably. When I think back of my first days as forum administrator (about 2 years ago) I could easily read all posts myself. There were about 600 registered forum users in total, but today there are over 17.000!

Oh well. I hope I can make a difference.

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)
Categories: Linux, Ubuntu

Overriding dynamic library calls (function interposition)

August 18th, 2009 Wesley 7 comments

About function interposition

I was wondering how I could override dynamic library calls in Linux, and I came across this technique known as function interposition. It is a powerful technique that allows you to override dynamic library calls. It might sound dull, but it can be very, very useful. There are some memory trace tools that make use of this technique to work, but perhaps a cooler example is the OpenGL capture system which was created by nullkey: it can capture OpenGL frames by overriding certain OpenGL functions. Another example are cheat tools (wallhacks, aimbots) which also make use of this technique a lot.

Some background

While Googling (did I spell that right?) I came across this recent blog article which explains the background very well. I will quote it here:

First, some background. When a program that uses dynamic libraries is compiled, a list of undefined symbols is included in the binary, along with a list of libraries the program is linked with. There is no correspondence between the symbols and the libraries; the two lists just tell the loader which libraries to load and which symbols need to be resolved. At runtime, each symbol is resolved using the first library that provides it. This means that if we can get a library containing our wrapper functions to load before other libraries, the undefined symbols in the program will be resolved to our wrappers instead of the real functions.

So if we create a custom shared library which overrides some of the functions of the original library, our functions will be called instead of those of the original library.

How to do it

  • Write new functions which override existing functions
  • Compile the written code to a dynamic library that is linked to the dynamic linking interface library
  • Use the LD_PRELOAD environment variable when running an application to preload your custom library before all other dynamic libraries

The article by Jay Conrod has an example which shows you the basic implementation of a simple memory allocation tracer.

I have also cooked up an example myself. Because I’ve been busy learning more about OpenGL, I thought that it shouldn’t be too hard to create a wallhack for one of my favourite games: Soldier of Fortune 2 running in Wine. Just for testing purposes of course! I am no cheater :D It turned out to be relatively simple, although my first tries weren’t so very successful:

  • Epic fail – At least I know my library is used now.
  • Partial success – Disabling depth testing completely was only a partial success.
  • Success – A debugger can tell that players are drawn using glDrawElements(). By knowing the number of elements for each character, we can disable depth testing selectively.
Soldier of Fortune 2 wallhack example

Soldier of Fortune 2 wallhack example

For those of you who are interested in the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
    Simple wallhack example for Soldier of Fortune 2 (Wine) in Linux using function interposition

    This code snippet was written by Wesley Stessens (wesley@ubuntu.com)
    It is released in the Public Domain.

    Compilation: gcc -Wall -ansi -pedantic -shared -ldl -fPIC glhack.c -o glhack.so
    Usage: LD_PRELOAD=glhack.so wine game.exe
*/


#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdint.h>
#include <GL/gl.h>

/* Override the glDrawElements function */
GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
    /* Store the actual function in a static function pointer */
    static void (*glDrawElements_)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) = NULL;
    if (!glDrawElements_) {
        glDrawElements_ = (void(*)())(intptr_t)dlsym(RTLD_NEXT, "glDrawElements");
        puts("GLHack: glDrawElements call has been overridden");
    }

    /* Disable depth testing if the number of elements to draw is one of the following, which means a player is being drawn */
    /* To avoid abuse of this code by cheaters, I have changed all count constants below to VALUEX */
    if (count == VALUE1 || count == VALUE2 || count == VALUE3 || count == VALUE4)
        glDisable(GL_DEPTH_TEST);
    else
        glEnable(GL_DEPTH_TEST);
    glDrawElements_(mode, count, type, indices);
}

Interesting thought about multiplayer cheats and Wine

If anti-cheat tools would perform a sanity check of the OpenGL or DirectX DLL, they would only find the virtual DLL’s when a game is run in Wine, right? I’m wondering whether this sort of cheats can be made undetectable then. In a way I hope not, because cheaters are very annoying when you’re playing a game, but on the other hand, it would be an amazing technological achievement. Anyway, anti-cheat tools like PunkBuster don’t even work with Wine at the moment, so it might be a non-issue. What are your thoughts?

VN:F [1.6.3_896]
Rating: +1 (from 1 vote)
Categories: C, Linux, OpenGL, Programming

My very own Linux from scratch

August 3rd, 2009 Wesley No comments

I started with a CLFS (Cross-compiled Linux From Scratch) installation yesterday. After major issues which I encountered when trying to boot the new kernel, I managed to create a very minimalistic kernel configuration which built a kernel that was able to boot up! I now have a very minimal Linux installation.

It’s not done yet, though. I will now have to install base system software, build a more advanced kernel, and then start building and integrating different software components of my personal choice. After this project I might either start my own Linux distribution (either from scratch, or based on Arch Linux) or just provide a repository for Arch Linux which contains some special software and help with Arch Linux development – because the goals of the Arch Linux distribution are very similar to mine. I also want to provide a repository with custom kernels and software which improve performance for all laptops that are sold by Hasselt University since 2008. I would however like to improve some things upstream as well, for example add a graphical installer and create an auto-system-configure tool which sets up Arch Linux for specific usage, and I’m not entirely sure yet whether these would be welcome changes upstream. If not, I might have to resort to an Arch Linux fork or my own distribution from scratch.

VN:F [1.6.3_896]
Rating: +1 (from 1 vote)

x86 Linux assembler

August 2nd, 2009 Wesley 4 comments

The last few days I’ve been looking at x86 Linux assembler programming. I think it’s important to know how the code which you write in higher-level languages gets translated to low-level instructions and in what way things like libc or the kernel are involved. With some knowledge of assembler you can not only directly optimize some slower operations by implementing them in low-level assembly and by utilizing specific processor features, but in general you will also learn in which ways you can optimize your software by just writing the high-level code a little bit different – by anticipating how your code will translate into low-level assembler instructions.

That was my motivation for trying to do a few things with the Netwide Assembler (NASM). The result is a simple demo which utilizes libc, GLUT and OpenGL to display a rotating pyramid and cube.

ogl.asm

compiled ogl.asm application running in Ubuntu 8.04

The resulting code can be viewed here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
; OpenGL example in x86 Linux assembler / NASM using Glut
; Author: Wesley Stessens (wesley@ubuntu.com)
;
; OpenGL calls to create pyramid and cube are from Jeff Molofee's OpenGL tutorial
; See: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=05
;
; Features:
;  - Calling C functions by cdecl conventions
;  - Using GLUT and OpenGL calls to perform 3D graphics
;  - Low-level framerate control
;
; Sample compile instructions:
; nasm -felf ogl.asm && ld -lglut -s -I/lib/ld-linux.so.2 -o ogl ogl.o
;
; This code is released as sample code in the public domain. Use it for whatever you want.
; Feel free to let me know if you found this code useful in any way.

; Glut
extern glutInit, glutInitDisplayMode, glutInitWindowSize, glutInitWindowPosition
extern glutCreateWindow, glutMainLoop
extern glutDisplayFunc, glutIdleFunc, glutReshapeFunc, glutKeyboardFunc
extern glutSwapBuffers

; Glu
extern gluPerspective

; OpenGL
extern glClearColor, glClearDepth, glDepthFunc, glEnable, glShadeModel
extern glClear, glLoadIdentity, glMatrixMode, glViewport
extern glTranslatef, glRotatef, glBegin, glEnd, glVertex3f, glColor3f

; Needed for framerate control
extern usleep

; Macros
%macro _3call 4
    push dword %4
    push dword %3
    push dword %2
    call %1
    add esp, 12
%endmacro
%macro _4call 5
    push dword %5
    push dword %4
    push dword %3
    push dword %2
    call %1
    add esp, 16
%endmacro

section .data
    title: db 'OpenGL in x86 Linux assembler / NASM using Glut', 0
    ; Data for FP math with 4 bytes
    n7: dd -7.0
    n6: dd -6.0
    n1p5: dd -1.5
    n1: dd -1.0
    p0p4: dd 0.4
    p0p5: dd 0.5
    p1: dd 1.0
    p1p5: dd 1.5
    p3: dd 3.0
    rottrm: dd 4.5
    rotsqm: dd -3.0

    ; Data for FP math with 8 bytes
    q0p1: dq 0.1
    q1: dq 1.0
    q45: dq 45.0
    q100: dq 100.0

    ; Data for framerate control
    mspf: dd 20000 ; ms per frame

section .bss
    ; Vars for rotation
    rottr: resd 1
    rotsq: resd 1
    ; Var for aspect ratio
    aspr: resq 1
    ; Vars for framerate control
    time: resd 2
    usecs: resd 1
    oldslp: resd 1

section .text
    global _start

fpsmanager:
    push eax
    push ebx
    push ecx
    push edx

    mov eax, 78 ; sys_gettimeofday
    mov ebx, time
    mov ecx, 0
    int 80h

    mov eax, [time + 4]
    sub eax, [usecs]
    mov ebx, [mspf]
    sub ebx, eax

    test eax, eax
    js keep_sleep
    test ebx, ebx
    js keep_sleep

    push ebx
    call usleep
    add esp, 4
    mov dword [oldslp], ebx
    jmp done_sleep

keep_sleep:
    push dword [oldslp]
    call usleep
    add esp, 4

done_sleep:
    mov eax, [time + 4]
    mov dword [usecs], eax

    pop edx
    pop ecx
    pop ebx
    pop eax
    ret

display:
    ; Prepare for drawing
    push dword 4100h ; GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT
    call glClear
    add esp, 4
    call glLoadIdentity

    ; Draw pyramid on the left of the screen
    _3call glTranslatef, [n1p5], 0, [n6]
    _4call glRotatef, [rottr], 0, [p1], 0
    push dword 9h ; GL_POLYGON
    call glBegin
    add esp, 4
    _3call glColor3f, [p1], 0, 0 ; Start drawing front face
    _3call glVertex3f, 0, [p1], 0
    _3call glColor3f, 0, [p1], 0
    _3call glVertex3f, [n1], [n1], [p1]
    _3call glColor3f, 0, 0, [p1]
    _3call glVertex3f, [p1], [n1], [p1]
    _3call glColor3f, [p1], 0, 0 ; Start drawing right face
    _3call glVertex3f, 0, [p1], 0
    _3call glColor3f, 0, 0, [p1]
    _3call glVertex3f, [p1], [n1], [p1]
    _3call glColor3f, 0, [p1], 0
    _3call glVertex3f, [p1], [n1], [n1]
    _3call glColor3f, [p1], 0, 0 ; Start drawing back face
    _3call glVertex3f, 0, [p1], 0
    _3call glColor3f, 0, [p1], 0
    _3call glVertex3f, [p1], [n1], [n1]
    _3call glColor3f, 0, 0, [p1]
    _3call glVertex3f, [n1], [n1], [n1]
    _3call glColor3f, [p1], 0, 0 ; Start drawing right face
    _3call glVertex3f, 0, [p1], 0
    _3call glColor3f, 0, 0, [p1]
    _3call glVertex3f, [n1], [n1], [n1]
    _3call glColor3f, 0, [p1], 0
    _3call glVertex3f, [n1], [n1], [p1]
    call glEnd

    ; Draw cube on the right of the screen
    call glLoadIdentity
    _3call glTranslatef, [p1p5], 0, [n7]
    _4call glRotatef, [rotsq], [p1], [p0p4], [p0p5]
    push dword 7h ; GL_QUADS
    call glBegin
    add esp, 4
    _3call glColor3f, 0, [p1], 0 ; Start drawing top face
    _3call glVertex3f, [p1], [p1], [n1]
    _3call glVertex3f, [n1], [p1], [n1]
    _3call glVertex3f, [n1], [p1], [p1]
    _3call glVertex3f, [p1], [p1], [p1]
    _3call glColor3f, [p1], [p0p5], 0 ; Start drawing bottom face
    _3call glVertex3f, [p1], [n1], [p1]
    _3call glVertex3f, [n1], [n1], [p1]
    _3call glVertex3f, [n1], [n1], [n1]
    _3call glVertex3f, [p1], [n1], [n1]
    _3call glColor3f, [p1], 0, 0 ; Start drawing front face
    _3call glVertex3f, [p1], [p1], [p1]
    _3call glVertex3f, [n1], [p1], [p1]
    _3call glVertex3f, [n1], [n1], [p1]
    _3call glVertex3f, [p1], [n1], [p1]
    _3call glColor3f, [p1], [p1], 0 ; Start drawing back face
    _3call glVertex3f, [p1], [n1], [n1]
    _3call glVertex3f, [n1], [n1], [n1]
    _3call glVertex3f, [n1], [p1], [n1]
    _3call glVertex3f, [p1], [p1], [n1]
    _3call glColor3f, 0, 0, [p1] ; Start drawing left face
    _3call glVertex3f, [n1], [p1], [p1]
    _3call glVertex3f, [n1], [p1], [n1]
    _3call glVertex3f, [n1], [n1], [n1]
    _3call glVertex3f, [n1], [n1], [p1]
    _3call glColor3f, [p1], 0, [p1] ; Start drawing right face
    _3call glVertex3f, [p1], [p1], [n1]
    _3call glVertex3f, [p1], [p1], [p1]
    _3call glVertex3f, [p1], [n1], [p1]
    _3call glVertex3f, [p1], [n1], [n1]
    call glEnd

    ; Update rotation
    fld dword [rottr]
    fadd dword [rottrm]
    fstp dword [rottr]
    fld dword [rotsq]
    fadd dword [rotsqm]
    fstp dword [rotsq]

    call glutSwapBuffers ; Swap buffers and display
    call fpsmanager ; Cap framerate if necessary
    ret

reshape:
    push ebp
    mov ebp, esp

    ; Prevent division by zero
    cmp dword [ebp+8], 0
    jne reshape_2
    inc dword [ebp+8]

reshape_2:
    fild dword [ebp+8]
    fidiv dword [ebp+12]
    fstp qword [aspr]

    push dword [ebp+12]
    push dword [ebp+8]
    push dword 0
    push dword 0
    call glViewport
    add esp, 16
    push dword 1701h; GL_PROJECTION
    call glMatrixMode
    add esp, 4
    call glLoadIdentity

    push dword [q100+4]
    push dword [q100]
    push dword [q0p1+4]
    push dword [q0p1]
    push dword [aspr+4]
    push dword [aspr]
    push dword [q45+4]
    push dword [q45]
    call gluPerspective
    add esp, 32

    push dword 1700h; GL_MODELVIEW
    call glMatrixMode
    add esp, 4

    pop ebp
    ret

keyhandler:
    ret

_start:
    ; Initialize glut
    push dword [esp+8]
    lea eax, [esp+8]
    push eax
    call glutInit
    add esp, 8
    push dword 1ah ; GLUT_RGBA|GLUT_DOUBLE|GLUT_ALPHA|GLUT_DEPTH
    call glutInitDisplayMode
    add esp, 4
    push dword 480
    push dword 640
    call glutInitWindowSize
    add esp, 8
    push dword 0
    push dword 0
    call glutInitWindowPosition
    add esp, 8

    ; Create window
    push title
    call glutCreateWindow
    add esp, 4

    ; Register functions
    push display
    call glutDisplayFunc
    call glutIdleFunc
    add esp, 4
    push reshape
    call glutReshapeFunc
    add esp, 4
    push keyhandler
    call glutKeyboardFunc
    add esp, 4

    ; Initialize OpenGL
    push dword 0
    push dword 0
    push dword 0
    push dword 0
    call glClearColor
    add esp, 16
    push dword [q1+4]
    push dword [q1]
    call glClearDepth
    add esp, 8
    push dword 203h; GL_LEQUAL
    call glDepthFunc
    add esp, 4
    push dword 0b71h; GL_DEPTH_TEST
    call glEnable
    add esp, 4
    push dword 1d01h; GL_SMOOTH
    call glShadeModel
    add esp, 4

    ; Frame rate cap initialization
    mov dword [oldslp], 0

    ; Enter main loop
    call glutMainLoop

    ; Exit (return with error code 0)
    mov eax, 1 ; sys_exit
    mov ebx, 0
    int 80h

I have also written two other smaller examples:
- marketing.asm is a really simple statistics application which calculates the ideal sample size given a few parameters
- alsawav.asm is a simple audio library which utilizes ALSA to play an unbuffered raw WAV/PCM sample

Please note that all these examples require an x86 Linux distribution. These examples will not work on any other operating system.

VN:F [1.6.3_896]
Rating: +3 (from 3 votes)

Akademy 2008: Great Experience

August 24th, 2008 Wesley 7 comments

Hello everyone! It’s been a very long time since my last blogpost, and I haven’t updated my blogsoftware in a long time. Apparently, some spammers noticed this as well and were able to add some hidden spam links in some of my pages. I should seriously update my WordPress one of these days…

Anyway. Let’s talk a bit about Akademy this year. It was my first Akademy and it was a great experience! I met a lot of interesting and fun people! Everyone seems to agree that this Akademy was the best one yet, so I’m very glad to have been a part of that, although honestly most work was done by Bart Cerneels and Wendy Van Craen.

The first day

The first day was the hardest day for the organization, or at least for me and Pieter Vande Wyngaerde. After helping out at the Akademy location (Campus De Nayer) we had to make sure everyone had a place to sleep at Roo?[sz]enda[ae]l (the name was spelled different on every sign!). The rooms list wasn’t all that clear, because the numbering was different from the room numbers, but after a while we were able to figure it out, and we were able to give everyone a place to sleep.

Resting out on the floor after all that hard work ;)

Resting out on the floor after all that hard work ;)

Party time!

On the second day I was just walking around the campus, helping the team with small things. I wasn’t able to see many talks, but I was able to at least see the Nokia keynote from Sebastian Nyström. A very interesting talk, although I’m still not sure exactly what direction Qt Software will be evolving towards with Nokia, but up until now it’s been going well, so that makes me happy enough for now.

Gouden Carolus Belgian BeerIn the evening it was party time: there was this social event at Het Anker in Mechelen, which meant free food and free Belgian beer! The “Gouden Carolus” beer is something even I – as a Belgian – had never drunk before. Personally, I think there are much better tasting Belgian beers, but maybe that’s just my personal taste. The beer was pretty strong though. But I’m sure that most of you noticed that :)

After the social event I went for a small evening stroll with some of the guys who were staying at Zandpoortvest. In the end, we walked all the way to the Zandpoortvest hostel, and after I had a look around the hostel, I had to walk all the way back to Rozendaal (I’ll just stick with this way of spelling it..) Unfortunately for me, I got lost. Too bad I didn’t have the N810 with its GPS (yet), otherwise I could’ve gotten back at Rozendaal a lot quicker. My cellphone batteries were dead as well – doesn’t this sound like some horror story? – so I just figured I’d walk and follow the signs pointing to Sint-Katelijne-Waver.

After a while I saw some arrows pointing to the train station, and from there, I was able to find my way back to Rozendaal. By then, it was around 5 am, and I had a big blister on my left foot from walking all night.

…I tried to stay up, but around 11 AM I felt really tired and I wanted to sleep a bit. And because of that I missed all the great presentations that I wanted to see! It was in the late afternoon somewhere that Pieter Verledens woke me up. Then I realized how late it already was and that I missed Zack Rusin’s Gallium3D talk, which I was looking forward to. Luckily, the talk was recorded and is available on blip.tv now (thanks to Bart Cerneels).

Nokia converts KDE developers to GNOME

The Mobile and Embedded day was one of the best days of Akademy. Not only because Nokia gave away a lot of Nokia N810 devices to more than 100 KDE developers, but also because the talks were really interesting. The big problem however is that it was a pretty busy day and I wasn’t able to see most of the talks (I really wanted to see the maemo, QEdje and OpenMoko talks as well). I ended up seeing only the OpenGL ES for Embedded Linux talk by Tom Cooksey, which was very interesting though. At the end of the talk he told us about the OpenPandora handheld device that will be released soon. Apparently it is a great device for OpenGL ES development. I found their website here: www.openpandora.org

Now, the title above this paragraph is inspired by Vincent Untz‘ blogpost. It refers to the free N810s that Nokia gave away. The devices run the Maemo OS, which is based on GNOME. And to be honest, I like Maemo a lot. It works very well. But I’m very interested in the progress that Marijn Kruisselbrink is making with porting KDE 4 to the Nokia internet tablets. Me myself, I haven’t done much with the device yet, aside from playing some games, listening to some music, and doing video calls with other KDE people ;) I did however manage to get some Qt applications ported to the device, but that was ridiculously easy. Hildon integration Just Works™ out of the box and there’s very little that has to be changed to make your application look great on the N810. Except for graphics operations which are a bit slow at the moment, as explained by Ariya Hidayat in his blog post, so I also hope that the performance problem gets fixed in Qt 4.5.

Nokia N810
The Nokia N810 Internet Tablet.

Oh. And my cat was chewing on my N810 adapter (even cats seem to like this gift from Nokia), so the pin doesn’t fit my N810 perfectly anymore. But it still works if I put it in carefully and don’t touch it, so I’m still good…

Boat and Barbecue

Thursday was a really nice day. A nice boat trip, and a very tasteful barbecue. I enjoyed it a lot. Jonathan Riddell was busy interviewing a lot of people, you can download the interviews from this link. I didn’t volunteer for an interview, but you can see me sitting in the back during interview number 44. That’s enough for me ;)

At the end of Akademy, Aaron and Chani treated us (the Akademy organisation team) to a nice dinner. Thanks for the good meal and the great stories.

Everyone had to leave back home on Friday or Saturday. Sad times. I’m planning to come to Akademy next year as well. It was a lot of fun this year.

To wrap it up, here are some random notes:

  • I’m not sure who’s the noisiest: the Amarok Wolves or Team Humongous
  • If you are in dire need of some music, maybe you can hire the A-Team!
  • Video’s of a lot of talks are available at http://stecchino.blip.tv/
  • The Emsys guys really like Mega Mindy
VN:F [1.6.3_896]
Rating: 0 (from 2 votes)
Categories: KDE, Linux, Open Source

Open source DJ mixxx’ing

January 6th, 2008 Wesley 3 comments

Sinds vorige week ben ik begonnen met mee te helpen aan de ontwikkeling van het open source DJ programma mixxx. Mixxx is een stabiel programma waarmee men live muziek kan mixen. Het heeft een aantal zeer interessante features, zoals bijvoorbeeld automatische ritmedetectie en ondersteuning voor een heleboel hardware.

Mixxx 1.6.0 with Collusion/WS/Green skin

Waar staan we vandaag? 1.6.0

Ik werk mee aan de nieuwe versie waarvan twee weken geleden een eerste bètaversie werd gelanceerd. Voor de nieuwe 1.6.0 versie zijn een heleboel nieuwe features gepland. Ik som even de belangrijkste veranderingen op:

  • Scratchen via timecoded vinyl-platen [ link naar flash video 1, video 2 ]
  • Kleurenschema’s voor skins
  • Nieuwe muziekbibliotheek (muziekbrowser)
  • Verbeterde ritmedetectie
  • Verbeterde ondersteuning voor MIDI-controllers (hardware)
  • HQ-equalizer toegevoegd
  • Audio core herschreven/vernieuwd
  • Ondersteuning voor LADSPA geluidseffecten
  • Live broadcasten over internet (Icecast, Shoutcast)
  • Rechtstreeks opnemen naar MP3, Ogg Vorbis, Wav, Flac

Ik werk momenteel aan de laatste twee punten. Het is niet zeker of het helemaal af zal raken voor de Hardy freeze in februari (het moment waarop programma’s naar Ubuntu 8.04 Hardy Heron geupload worden en niet meer aangepast mogen worden) maar Ogg Vorbis Icecast/Shoutcast-ondersteuning is zo goed als af, dus dat zal er waarschijnlijk zeker inzitten.

Zelf kijk ik uit naar de ondersteuning voor LADSPA geluidseffecten, maar ik vermoed dat dat niet af zal raken voor de 1.6.0-versie. Dan maar wat langer wachten…

Evolutie van de broadcasting code

Mixxx Live Broadcasting Preferences

Zoals eerder gezegd ben ik momenteel bezig met het implementeren van Icecast/Shoutcast ondersteuning zodat we een mix rechtstreeks over internet kunnen broadcasten. Aanvankelijk dachten we dat het simpel zou zijn om dit systeem te implementeren (gewoon libshout gebruiken) maar al snel bleek dat we eerst nog een encoder moesten schrijven. Ik ben de laatste dagen dus vooral bezig geweest met het schrijven van een Ogg Vorbis-encoder met behulp van libvorbis, libogg en libvorbisenc.

Afgezien van het feit dat er voor libvorbis geen technische API-documentatie beschikbaar is, is het ons uiteindelijk toch gelukt om de encoder werkend te krijgen. Alles ging goed, maar de audio latency was nu wel verhoogd omdat de ‘audio callback thread’ voor een korte periode geblokkeerd werd wanneer de encoder zijn werk deed. Toen we ook nog beseften dat we om metadata te updaten een nieuwe stream moesten initialiseren was het onvermijdelijk om een nieuw systeem te ontwerpen om de encoder parallel in een aparte thread te laten draaien (multithreaded) met een eigen buffer.

Albert ging hiermee aan de slag en na twee of drie dagen knoeien presenteerde hij een nieuwe ‘engine’ (de SideChain-engine) aan ons die de audio buffert voor andere engines (zoals de broadcast engine) en deze engines in een aparte thread draait. Het resultaat is lage audio latency en geen enkel performanceprobleem meer. Ook werd het totale CPU-verbruik verlaagd omdat de encoder nu iets minder vaak aangeroepen wordt.

Om het schematisch voor te stellen:

voor: [ afbeelding: Oorspronkelijke Broadcast Implementatie ]
na:
[ afbeelding: Threaded Broadcast Implementatie ]

Wat moet er nog gedaan worden? De SideChain-engine moet nog een klein beetje aangepast worden, er moet nog een MP3-encoder worden geschreven, het instellingenvenster moet afgemaakt worden, en tenslotte moet de code wat opgeschoond worden, en moet alles grondig getest worden!

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)

Neem je Linux (of Wine) games op!

December 27th, 2007 Wesley 2 comments

Het laatste jaar zijn er twee projecten ontstaan die het mogelijk maken om OpenGL en Alsa op te nemen zonder al te veel verlies van performance. Voor de gamers die niet weten waarover ik het heb: dit is bij wijze van spreken ‘FRAPS for Linux’. Ik heb beide projecten uitgetest en ze werken allebei prachtig: yukon en glc.

glc recording

Klik hier voor de volledige video-opname op YouTube

Dit is Aquaria Demo in Wine
opgenomen met glc op 1024×768
met Compiz ingeschakeld.

Je bent vrij om te gebruiken wat voor jou het beste werkt:

Persoonlijk ben ik momenteel voorstander van glc omdat de ontwikkelaar zéér snel is met het reageren op bugreports en omdat glc is geoptimaliseerd voor multi-core systemen. Ook heeft glc enkele speciale mogelijkheden zoals on-the-fly color conversion van BGR naar YV12 (geeft grotere compressie) en je kan zowel QuickLZ als LZO gebruiken om de stream on-the-fly te comprimeren. Een andere speciale feature van glc is de mogelijkheid om meerdere OpenGL of Alsa streams tegelijkertijd op te nemen.

glc werkte perfect bij mij, maar ik had een klein probleem met het opnemen van sommige games in Wine (problemen met audio en af en toe een crash). Na een kort gesprek met de ontwikkelaar (nullkey) en na het opsturen van enkele gdb traces werd het probleem binnen 10 minuten volledig opgelost door de ontwikkelaar. Prachtig, toch? De nieuwste versie van glc is momenteel 0.4.4 en bevat de Wine patches.

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)
Categories: Linux, Multimedia

SMPlayer Overlay Patches

December 9th, 2007 Wesley 2 comments

SMPlayer Time Overlay Patch

Ik ben bezig aan een patch voor SMPlayer voor mezelf:

  1. ik wil de huidige tijd kunnen zien zonder full-screen te verlaten (en zonder een klok te kopen) – zoals je kan zien op de bovenstaande screenshot heb ik dat reeds voor elkaar gekregen.
  2. ik wil de afspeeltijd van de film als een klein balkje op het scherm zien, niet via het tekstuele OSD, en ik wil eveneens de film kunnen doorspoelen door op een willekeurige plaats op mijn mooie alpha-transparante balk te klikken… want dat is veel mooier dan zo’n uitschuivend balkje dat je video naar boven duwt :)

Technische details:

  • mplayer gepatched en gecompileerd met vf_overlay patch
  • QPainter (van Qt 4.3) tekent de klok en tekst
  • getekende bitmap wordt vertaald naar het benodigde formaat en naar een gedeelde geheugenplek geschreven
  • mplayer (vf_overlay) leest de bitmap uit en legt hem over de video heen
  • mediaspeler waar de patch in wordt ontwikkeld is SMPlayer (mplayer frontend)

Ik denk niet dat ik deze patch upstream zal opsturen, tenzij er veel vraag naar is. De reden daarvoor is simpelweg dat je een onofficiële mplayer patch nodig hebt (vf_overlay patch) om van deze patch gebruik te maken, en (ik maak een gok) 95% van de smplayer-gebruikers zijn dus sowieso niets met deze patch.

Ik ben wel van plan om de patch op het forum van SMPlayer te plaatsen voor degenen die het eens willen bekijken of zelf willen proberen, maar de patch is momenteel nog niet in een “releasebare” status.

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)
Categories: C++, Linux, Multimedia, Programming, Qt