Generador de letras de reggaetón

Disclaimer: this is completely unrelated to computer science or VOIP :D.

Este post es mi respuesta a @mharcos y @markosbenitez quienes me desafiaron a hacer un programa que genere letras de reggaetón a partir de unas instrucciones (abajo) posteadas en facebook.

Con un script hecho en PHP fui capaz de generar letras como esta:

Gata yo quiero azotarte fuerte hasta manhana
Chica yo quiero cogerte lento hasta manhana
Chica vamos a castigarte duro hasta manhana
Perra vamos a cogerte fuerte hasta que salga el sol

[CORO]
azotarte azotarte azotarte, toda la noche, suave … x3

Perra vamos a castigarte duro todo el dia
Perra yo voy a castigarte duro hasta manhana
Gata vamos a cogerte suave todo el dia
Chica yo quiero encenderte rapido hasta el amanecer

[CORO]
azotarte azotarte azotarte, toda la noche, lento … x3

Perra yo quiero darte suave hasta manhana
Mami yo vengo a azotarte lento hasta que salga el sol
Chica yo voy a encenderte suave hasta el amanecer
Chica vamos a castigarte lento hasta el amanecer

[CORO]
darte darte darte, hasta que salga el sol, suave … x3

Con éste enlace podés generar más letras aleatorias. Con cada recarga se genera una nueva.

Para los entendidos del tema, acá les dejo el script.

[php]

define(‘RENGLONES_POR_ESTROFA’, 4);
define(‘MAXIMO_ESTROFAS’, 3);
define(‘NL_MARKER’, “n”);

$bloque_1 = array(‘Mami’, ‘Gata’, ‘Perra’, ‘Zorra’, ‘Chica’);
$bloque_2 = array(‘yo quiero’, ‘vamos a’, ‘yo voy a’, ‘yo quiero’, ‘yo vengo a’);
$bloque_3 = array(‘castigarte’, ‘cogerte’, ‘encenderte’, ‘darte’, ‘azotarte’);
$bloque_4 = array(‘duro’, ‘rapido’, ‘lento’, ‘suave’, ‘fuerte’);

$bloque_5 = array(‘hasta que salga el sol’,
‘toda la noche’,
‘hasta el amanecer’,
‘hasta manhana’,
‘todo el dia’);

$bloque_6 = array(‘sin miedo’,
‘sin anestesia’,
‘en el piso’,
‘contra la pared’,
‘sin compromiso’);

function GenerarLetra()
{
$estrofa = array();
$letra = array();

for ($i = 0; $i < MAXIMO_ESTROFAS; $i++)
{
$estrofa = array();

for ($j = 0; $j < RENGLONES_POR_ESTROFA; $j++)
array_push($estrofa, GenerarRenglon());

array_push($letra, implode(NL_MARKER, $estrofa).NL_MARKER);
array_push($letra, “[CORO]”);
array_push($letra, GenerarCoro().” … x3″.NL_MARKER);
}

print implode(NL_MARKER, $letra);
}

print GenerarLetra().”n”;

function GenerarRenglon()
{
global $bloque_1, $bloque_2, $bloque_3, $bloque_4, $bloque_5, $bloque_6;

return “{$bloque_1[rand() % count($bloque_1)]} “.
“{$bloque_2[rand() % count($bloque_2)]} “.
“{$bloque_3[rand() % count($bloque_3)]} “.
“{$bloque_4[rand() % count($bloque_4)]} “.
“{$bloque_5[rand() % count($bloque_5)]}”;
}

function GenerarCoro()
{
global $bloque_3, $bloque_4, $bloque_5;

$verbo = $bloque_3[rand() % count($bloque_3)];

return “$verbo $verbo $verbo, {$bloque_5[rand() % count($bloque_5)]}, {$bloque_4[rand() % count($bloque_4)]}”;

}

 

[/php]

Espero les sirva de algo xD

Huawei modem as an answering machine

Here is a summary of my effort trying to make chan_dongle to work:

… I couldn’t …

and I don’t even tried, I’d rather prefer to write my own channel, but why? When three semi-functional projects with the same device and the same technology fails in completing their objectives, there must be something wrong with the approach probably because doing it as an Asterisk channel adds unnecessary complexity.

The project

I spent 2 days reading docs about AT and after I gained some expertise I tested them using minicom with an E177 modem. Everything worked as it should except for the audio.

Consider this scenario.

1. modem connected to USB port.
2. minicom opening data port (/dev/ttyUSB0 in most cases).
3. an external phone for making calls.

Now the test was as follows:

1. I called to the modem using the external phone.
2. I answered the call from minicom.
3. I started reading the audio port (/dev/ttyUSB1).
4. I hung up the call.

The signaling was fine, the call handling was fine but no audio was received from /dev/ttyUSB1. I wasted precious time looking for an answer because I was asking the wrong question, I even recurred to stackoverflow.com but without luck.

I explored chan_dongle‘s source tree expecting to find some missing initialization sequence but it’s really complicated to follow the code execution path on a heavily multi-threaded application like Asterisk so I decided to use strace to attach it to Asterisk’s PID and sniff for write syscalls to get a clue of what the channel was doing. My guess certainly worked: I missed the AT^DDSETEX=<diag-port> after the call is connected so I repeated the test including this command right after the call was answered and suddenly an audio stream was flowing through the port.

[bash]

strace -f asterisk 2>&1 | grep write | grep AT
[pid 14715] write(17, “ATr”, 3 <unfinished …>
[pid 14715] write(17, “ATZr”, 4) = 4
[pid 14715] write(17, “ATE0r”, 5) = 5
[pid 14715] write(17, “AT+CGMIr”, 8) = 8
[pid 14715] write(17, “AT+CGMMr”, 8) = 8
[pid 14715] write(17, “AT+CGMRr”, 8) = 8
[pid 14715] write(17, “AT+CMEE=0r”, 10) = 10
[pid 14715] write(17, “AT+CGSNr”, 8) = 8
[pid 14715] write(17, “AT+CIMIr”, 8) = 8
[pid 14715] write(17, “AT+CPIN?r”, 9) = 9
[pid 14715] write(17, “AT+COPS=0,0r”, 12) = 12
[pid 14715] write(17, “AT+CREG=2r”, 10 <unfinished …>
[pid 14715] write(17, “AT+CREG?r”, 9) = 9
[pid 14715] write(17, “AT+CNUMr”, 8) = 8
[pid 14715] write(17, “AT^CVOICE?r”, 11) = 11
[pid 14715] write(17, “AT+CSCA?r”, 9) = 9
[pid 14715] write(17, “AT+CSSN=1,1r”, 12) = 12
[pid 14715] write(17, “AT+CMGF=0r”, 10) = 10
[pid 14715] write(17, “AT+CSCS=”UCS2″r”, 15) = 15

[/bash]

Answering machine

I decided to write a program to try out what I learned these days and this project came to my mind. It might not be the best execution of an idea but hopefully will help me to master the techniques required to make and receive phone calls using Huawei modems in a minimalist scenario where debugging is not a reason to shoot yourself in the face.

The program connects to the modem and waits for an incoming call which when received, is picked up and a prerecorded sound file is played to the caller. It’s a pretty straightforward idea and involves 80% of what is necessary to implement an Asterisk channel that does the same in another context.

[bash]$ /answering_machine /dev/ttyUSB0 /dev/ttyUSB1 /home/carlos/rec.raw [/bash]

– The 1st parameter is the data port.
– The 2nd paramater is the audio port.
– The 3th paramater is an arbitrary signed 16bit PCM 8000 Hz file.

Having supplied those arguments, the program picks up any incoming call and plays the file pointed by the third parameter.

You can find the code here and for now, to compile it you have to import it as an Eclipse project because the Makefile is missing (for now).

Dinstar DWG2000 SMS API stable release

I’ve finished the first stable release of the DWG2000 messaging API. I tested it dozens of times and appears stable after 24 hours of constant running. I’m aware of the memory leaks but I’ll fix this issue as soon as I can.

The code is pretty straightforward and self explanatory. By now this is just for personal use but if any of you are working with the same family of products, I can definitely help you. It is not ready for production, but it works.

[c]
/*
* main.c
*
* Created on: Mar 28, 2012
* Author: caruizdiaz
*/

#include “util.h”
#include “dwg/dwg.h”
#include “networking/ip_socket.h”

void new_sms_handler(dwg_sms_received_t *sms)
{
LOG(L_DEBUG, “new sms from %s. Len: %d, Text: %sn”, sms->number, sms->message.len, sms->message.s);
}

void status_handler(dwg_ports_status_t *status)
{
int index = 0;

LOG(L_DEBUG, “tNumber of ports: %dn”, status->size);

for (index = 0; index < status->size; index++)
{
LOG(L_DEBUG, “tPort%d: %dn”, index, status->status_array[index].status);
}
}

void msg_response_handler(dwg_sms_response_t *response)
{
LOG(L_DEBUG, “tResponse from %sn”, response->number);
}

int main(int argc, char** argv)
{

dwg_message_callback_t callbacks = {
.status_callback = status_handler,
.msg_response_callback = msg_response_handler,
.msg_sms_recv_callback = new_sms_handler
};

dwg_start_server(7008, &callbacks);

str_t des = { “0981146623”, 10 };
str_t msg = { “hola”, 4 };

for(;;)
{
getchar();
dwg_send_sms(&des, &msg);
}

}
[/c]

Huawei modems with Asterisk, another frustration

There are many: chan_mobile, chan_datacard, chan_dongle. I tried them all but none of them actually “works”.  They failed in controlled lab environments, they worked for periods of time but ended crashing the module and Asterisk itself.

At the time of writing this post the frustration is eating me. I spent the weekend trying to make chan_dongle to work with an E177 modem which a friend of mine bought from Amazon two weeks ago.

Chan_dongle is an effort from a developer who decided to share his work with us, I’m not criticizing him, I’m just publishing the results of my lab test along with some of the frustration originated from it.

I’ll read the code, try to figure out what’s happening and If I succeed, I’ll publish the results here.

 

Opensource DWG2000 messaging API

In my spare time I do some consulting jobs mostly about telecom stuff and in one of these jobs I wrote a Dialer software for Asterisk which makes phone calls to users (numbers) loaded from a database. If the call is successful the program must inform the called party about what just happened by sending a SMS. Everything was OK until this feature was required.

We used a 8 ports DWG2000 GSM gateway manufactured by Dinstar which works really fine in terms of overall performance and voice quality. It also supports sending/receiving SMS’s but the API exposed works only on Windows machines and since the source code of the driver remains undisclosed, we (I’m part of a team) were unable to port it to Linux. What they do provide is a detailed protocol specification with enough documentation to implement it by myself and the result of that effort can be found in my github account.

It is still in a very early stage but I’m planning to implement the whole protocol soon but for now, it works for sending and receiving SMS’s, it suited quite well the requirements of my last consulting job.