Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre python (publicaciones antiguas, página 8)

Adventures in Hi-Fi

As I blogged ear­li­er I am writ­ing a game (and yes, it's pret­ty much playable al­ready).

One thing I did­n't men­tion is that I nev­er wrote a game be­fore. Yeah, I know ev­ery­one does it as one of his first pro­ject­s, but I nev­er did.

So, there are some things I re­al­ly have no clue about 1, like sound and mov­ing graph­ics around.

For the graph­ics stuff, QCan­vas is just fine and dandy, but to make things bloop and war­ble and squeak when the time is right, I found Qt's sound sup­port some­what de­press­ing.

Come on, NAS? Who us­es that? And what about mu­sic? I had no idea.

So, I start­ed try­ing to fol­low one of my lead­ing prin­ci­ples of de­vel­op­men­t: find a way to make it Some­one Else's Prob­lem (T­M).

The usu­al way to do that is find­ing a li­brary that han­dles the prob­lem, write min­i­mal glue, stick it to the side of the pro­gram, tell the pro­gram that's his new ar­m, and for­get about it quick­ly.

Here's what I found.

Mi Dios!

I thought I should start by adding one of those an­noy­ing lit­tle tunes ev­ery game has. It's just a game tune, I don't want to have to in­clude a 3MB OGG file for it, so I want­ed an in­stru­men­t-based for­mat.

I re­mem­bered MI­DI tunes. You may know them as ring­tones nowa­days, but they used to be just cheesy tunes gen­er­at­ed by your SBPro's FM gen­er­a­tor, not your phone.

In fac­t, I re­mem­ber hav­ing a lit­tle prog­gie called playmidi, that would do that in Lin­ux.

Well, it seems that in the past few years, ei­ther sound cards have for­got­ten how to play them, they fell out of fash­ion, or some­thing, be­cause the on­ly things I found that could play MI­DI are mon­strosi­ties that re­quire a 9MB dig­i­tal in­stru­ment set. And how was I to in­clude that along with my 25KB game???

So, what's nex­t? I had a C64, so...

MOD me up!

MOD files are like MI­DI files, on­ly the MOD in­cludes it's own in­stru­ment set, called sam­ples, and in­struc­tions on how to re­peat and al­ter those sam­ples to make a tune.

Good news: there are nice-­sound­ing, fun­ny MOD files that are about 30KB in size.

Bet­ter news: There is a pop­u­lar li­brary to play them! It's called Mik­mod, and your dis­tro has it (and it's a de­pen­den­cy for KDE's mul­ti­me­dia pack­ages too).

Even bet­ter news: It has sup­port for play­ing sim­ple sounds (sam­ples in mod lin­go) by call­ing a cou­ple of func­tion­s.

Awe­some news: It in­cludes a soft­ware mix­er so you can just tell it to play this, then play that, then that, and a tune in the back­ground, and ev­ery­thing sounds at the same time.

So, we have a win­ner. This ba­by can han­dle ev­ery­thing I need for the game!

But... is that a snake in your pock­et?

I can't find a Python bind­ing for it. I am sure as soon as I post this ar­ti­cle some­one is go­ing to come up and tell me, here they are, mo­ron! But I just can't find any.

So, I de­cid­ed to do some­thing I want­ed to do al­ready and learn to use Pyrex. Pyrex is a tool to write python ex­ten­sion­s, with al­most-free ac­cess to C li­braries, in an al­most-python lan­guage (on­ly mi­nor syn­tax dif­fer­ences).

That way, I could write a Python mod­ule to use Mik­mod.

You know what? It was al­most scar­i­ly sim­ple 2. I did­n't wrap all of Mik­mod 3 be­cause I don't need it, but now I can do stuff for games and apps al­most triv­ial­ly.

Even more: Pyrex has awe­some dis­tu­tils sup­port, so build­ing the ex­ten­sion­s, usu­al­ly a pain in the rear, is triv­ial (most­ly you just copy and delete stuff, with some search and re­place).

One thing I found I did nice­ly is this: Mik­mod re­quires you to call Mik­mod­_Up­date ev­ery once in a while so it fills the sound­card's buf­fer with stuff to play. If you don't, it skip­s.

So, I just start­ed a thread that loops and takes care of it. You don't even have to know about it to use the ex­ten­sion. Oh, sure, if your Mik­mod is not thread­safe, it break­s. Well, get a de­cent Mik­mod pack­age, then.

How does it look?

Here's a whole noisy prog­gie

#Load the modules
import mikmod, time
#Init the library
mikmod.init()
#40 voices, 20 for music, 20 for random sounds (overkill)
mikmod.setNumVoices(20,20)
#Enable sound, starts the thread that pushes sound, too
mikmod.enableOutput()

#Create a module, that is, a music track
module=mikmod.Module("BasicInstinct.mod")

#Load two samples, just a couple of noises
s1=mikmod.Sample("lost.wav")
s2=mikmod.Sample("swap.wav")

#Start playing the song
module.play()


#For the duration of the song, each second, make some noise


while module.active():
        s1.play()
        time.sleep(0.5)
        s2.play()
        time.sleep(0.5)

#Close the mikmod library, stop the thread, etc.

mikmod.exit()
1

As if that would sur­prise any­one!

2

On the oth­er hand... wait­ing for stuff to com­pile... how quain­t.

3

Ac­tu­al­ly, I am wrap­ping al­most all of Mik­mod, I am just not ex­pos­ing it to Python be­cause I don't need it.

A good web-based password changer?

Does such a thing ex­ist? There are dozen­s, but none seems very good.

By good I mean:

  • Has been main­­tained more re­­cen­t­­ly than 4 years ago.

  • Works via PAM (and just plain work­s)

  • Is not aw­­ful to in­­stall

  • Does­n't make you do weird stuff like run­n­ing a SUID httpd (yes, I ac­­tu­al­­ly saw that on­ce)

  • se­cure (au­dit­ed?)

  • read­­able sources

  • runs as a non-priv­i­leged us­er.

Usu­al­ly this would be a SUID root cgi-bin, which is some­what scary, and it would seem to me un­nec­es­sary.

Since the us­er will pro­vide the cur­rent pass­word, it should be pos­si­ble for a non-priv­i­leged process to first switch to the de­sired us­er and then change the pass­word, right?

Maybe some­one can tell me. Or do I have to write it? I mean, it's go­ing to be a python CGI if I do, and noone's gonna like it ;-)

Good news, Bad news

Good news: It seems I have been ac­cept­ed to teach a PyQt tu­to­ri­al at akade­my.

Bad news: a kit­ten I had adopt­ed last mon­day died on sat­ur­day night. She was a sick kit­ten, and had a res­pi­ra­to­ry in­fec­tion. An­tibi­otics helped for a few days, she looked very hap­py on fri­day, but on sat­ur­day she woke up weak­er, and noth­ing I or the vet­eri­nar­i­an did helped.

She died on my lap that night.

I am a grown up, and I had on­ly had her for 5 days, so this should­n't be im­por­tant at al­l, but it is :-(

There goes Captain Beto, through space!

Here is a new re­al­time PyQt tu­to­ri­al. For those who have not seen the first one, here's the main idea:

  • I de­­cide I want to write some­thing

  • I write it (some­what) quick­­­ly.

  • I write a de­scrip­­tion of what I am do­ing, as I am do­ing it, and slap some time­s­tamp­s.

In this par­tic­u­lar in­stance, on a dis­cus­sion at the dot I had to open my mouth about how writ­ing a spa­tial file man­ag­er is easy.

Well, here's a piece of one. In par­tic­u­lar, it's a sort of sim­ple spa­tial file brows­er since it does­n't man­age files at al­l, but it's a start ;-)


Contents © 2000-2020 Roberto Alsina