This page refers to an old project that I do not maintain anymore and was left online for historical reasons only. Please have a look at the new page about Seren.


parole-conference is a simple voip program that allows you to create a voice conference from the terminal, with up to 10 participants, without having to register accounts, exchange emails, add people to contact lists etc.
It creates a dynamic, peer-to-peer network of equivalent nodes which can exchange text or audio data using a udp connection.


parole-conference is released under the GNU GPLv3 license.

How to compile parole-conference

parole-conference is written in C and uses alsa to access the sound card and libopus to compress the audio stream. Since it is a relatively simple program, there is no configure script. In order to compile parole-conference you need:

  1. gcc
  2. make
  3. pkg-config
  4. libasound
  5. libopus
  6. libncurses

Under Debian/Ubuntu all the dependencies should be satisfied by installing the following packages:

build-essential pkg-config libasound2-dev libopus-dev libncurses5-dev libncursesw5-dev

If your distribution is too old and does not provide a package for libopus, you can build it from source by running the following commands:

$ mkdir src
$ cd src
$ wget
$ tar xvzf opus-1.0.3.tar.gz
$ cd opus-1.0.3/
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
# you can later uninstall with:
#$ sudo make uninstall

Once the dependencies are satisfied, you can compile the program simply with:

$ make

If you want to clean the build directory just run:

$ make clean

The resulting binary can be put, for example, in /usr/local/bin or can be run from the local directory.

Using parole-conference

You can access the help by running:

$ ./parole-conference -h
parole-conference, ver. 0.10alpha17

Usage: parole-conference [options]
       -h             print help
       -v             increment verbosity level
       -n nick        set nickname
       -p port        listening port            (8110)
       -b bitrate     set bitrate in bit/s      (16000)
       -d audiodev    set playback audio device (hw:0,0)
       -D audiodev    set capture audio device  (playback device)

The values in parentheses on the right are the default values.
To create a conference the first node starts the program with:

$ ./parole-conference -n NICK

where NICK is of course your nickname. The program will now listen for incoming connection on udp port 8110 (you can change this port with -p option). Note that if you are using a router from a home connection and wants people to be able to call you from the outside, you'll most likely need to forward this port.

People that want to join a conference will need the IP address of one of the participants. After starting the program with the same command line as above, they will type /c host[:port] to connect to an active conference, where host can be either an IP address or a hostname, and port can be omitted when using the standard 8110 port.

When the program is running, type /h to access the online help. The available commands include /i to print information about the status of the program and the network/participants, /m or F5 to mute the microphone, /g to set a software gain for the microphone and /b to change bitrate on the fly.

Audio options

parole-conference uses alsa for audio capture and playback. You can specify the alsa device to use with -d option. If you get and error with the default device 'hw:0,0', try 'plughw:0,0'. Use the option -D to select a capture device different from the playback device. It should be possible to use pulseaudio with both options using the device 'pulse'.
Note that internally parole-conference uses the following format: 2 channels, 48000Hz sampling rate, s16_le format. So if your sound card does not support this format you're likely to get an error when alsa is initialized.

To choose the initial bitrate of the compressed opus stream, option -b can be used. The default is 16000 bit/s and should give very good quality with a typical bandwidth of 2 kbyte/s for each stream.


parole-conference supports basic encryption with a symmetric key (that is, people wanting to make an encrypted conference must choose a common key). This key is 128-bit long, and can be represented by a 32-char hexadecimal number. To encrypt a call all the participants must use the /e command to set a key. This can be done before starting or joining a conference or in the middle of the call, thus allowing the users to change it on the fly if necessary. If the key you chose is composed of less than 32 characters, it will be padded with '0's. A key composed of all '0's will disable encryption.
Note that a key could be created from a passphrase with the following command:

$ echo -n "put passphrase here" | md5sum | cut -b 1-32

Calls recording

To start recording a call to a wave file use the /r command. A message containing the name of the file will be printed to inform you that the recording has been started, and the letters "REC" will appear in red on the bottom left corner of the window, next to the call timer. Type /r again to end the recording.


Screenshot of parole-conference in action:


The values on the status bar on the bottom have the following meanings:


The following versions of parole-conference are available for download. We recommend you to download the latest version.

WARNING: Please note that parole-conference is still in development and it should be considered alpha software: this means that new functions will be added and/or the protocol can change, thus the backward compatibility is not guaranteed.


Development chat, testing and support happens on the #parole-conference IRC channel on the FreeNode IRC network.


version 010alpha17:

	* Added support for calls recording in .wav format
	* Fixed input of long lines (up to 1000 chars)

version 010alpha16:

	* Improved messages in case of wrong or missing key
	* Do not die when opus_decode() fails
	* Improved logging (timestamps, append to log file)

version 010alpha15:

	* Added xtea-cbc encryption support

version 010alpha14:

	* /i output: print node pcm length in ms
	* /i output: added node MUTE status
	* /i output: added local node
	* Use total number of packets at the denominator when computing packet loss
	* Rename packets_count to packets_received in struct node
	* Better /g command parsing
	* Cosmetic changes/improvements
	* Improved README
	* Added Changelog

version 010alpha13:

	* Added loopback support to hear back your own voice (command /l or F6)

version 010alpha12:

	* Added option -D to select a capture device different from the playback device
	* README improvements

version 010alpha11:

	* network.{c,h}: added packet_relay() and packet_from_relay_to_relayed() functions
	* UDP_PACKET_TYPE_* macros moved to network.h
	* Save program name and version to log file
	* Cosmetics changes and README improvements

version 010alpha10:

	* Makefile: network.h dependency fix
	* network.{c,h}: added packet_audio(), packet_nop(), packet_end(), send_packet_to_all() functions
	* Improved comments

version 010alpha9:

	* Major rework and clean-up: added network.{c,h} and nc.{c,h}
	* Important rework: deleted -l and -c options
	* msgbuf, fplog and nctx are now global variables
	* Limit input line length based on windows width
	* UTF-8 support by linking with -lncursesw
	* Added setlocale() call
	* Prefix 'guest' to random nick
	* Disabled -a option and questions/answer mechanism
	* Changed TIMEOUT to 300 (6s)
	* Deleted SIGUSR1 from signal handler
	* rw.c: deleted '& 0xFF' from write functions
	* Deleted notes.h
	* It's probable I've forgotten some other changes :)

version 010alpha8:

	* ncurses input: skip KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT
	* Changed log_msg() to print_msg() for many packets errors
	* Questions/answers mechanism improvement
	* Added basic tones function
	* ONE_OPUS_FRAME macro (value in alsa frames)
	* Deleted PCM20msLEN macro
	* Improved comments

version 010alpha7:

	* Repeat call request every 2s (using relay if necessary)
	* Added call_new_nodes() function
	* Apply timeout to all nodes regardless of knows_about_me status
	* Added delete reason in node_delete()
	* Deleted node_has_open_port()

version 010alpha6:

	* Added packet relay support: UDP_PACKET_TYPE_RELAY and UDP_PACKET_TYPE_RELAYED
	* Added node_has_open_port() function based on port number

version 010alpha5:

	* Changed MUTE color to red in status bar
	* Added ic_mute counter (total time is ic_talk+ic_mute)
	* Mic softwar gain algorithm slightly optimized for superscalar processors
	* Added find_peak_int32() slightly optimized for superscalar processors
	* Make all local function static
	* Added UDP_PACKET_TYPE_NOP to avoid sending silence when mic is muted
	* audio.c: added device name in verbose and error messages
	* Small code clean-up

version 010alpha4:

	* Major rework
	* Nodes: from statically allocated node array, to array of pointers
	  and dinamically allocated structures
	* Delete outer while() loop
	* Added bandwidth info in /i output

version 010alpha3:

	* Safer /b command parsing
	* Added software mic gain (/g command)
	* MBS changed to 512
	* PCMBUFLEN changed to 15*20=300ms
	* MAX_NUMBER_OF_NODES changed to 9 (thus 10 in total)
	* Small code clean-up

version 010alpha2:

	* Status bar: [  --  ] -> [ MUTE ]
	* ESC and F5 shortcuts
	* Support for ncurses window resize
	* Added print_bars() function

version 010alpha1:

	* Improved and colored status bar
	* Safer /k command parsing
	* Improved /i output
	* Input line 130 chars max
	* Moved alsa init and encoder creation up
	* ncurses colors
	* Added timeout parameter in node_delete()
	* resolve_address() output to ncurses window
	* PCM20msLEN macro
	* LOGFILE macro
	* Clean-up and comments improvements

version 010alpha0:

	* Initial release

Valid XHTML 1.0 Strict

Copyright (C) 2013 Giorgio Vazzana