Kai Vehmanen
02112002
This approach has two benefits. First, it's possible to keep the API small, and thus make it easier to port ECI to new languages. Secondly, it's possible to keep ECI relatively stable. Ecasound itself is a large, developing library. New features are added all the time, and from time to time, older parts of the library will get rewritten to better suit new uses. Now for application developers wanting to take advantage of libecasound, these constant changes are very annoying, especially if your specific app doesn't need the latest new features. In these cases, ECI is the best choice.
Specific tasks ECI is aimed at:
Here's a list of services provided by all ECI implementations:
The C implementation of ECI is not directly linked against the main ecasound libraries. Instead, the it launches the ecasound executable on the background and uses command pipes to communicate with it.
The launched ecasound executable can be selected by using the ECASOUND environment variable. If it is not defined, the C ECI implementation will try to launch ``ecasound'' (ie. has to be somewhere in PATH).
In addition to the C implementation, this also affects all ECI implementations that are based on the C version. Currently this includes at least the Perl, PHP and Python ECI modules.
#include <iostream> #include <unistd.h> #include <eca-control-interface.h> int main(int argc, char *argv[]) { double cutoff_inc = 500.0; ECA_CONTROL_INTERFACE e; e.command("cs-add play_chainsetup"); e.command("c-add 1st_chain"); e.command("ai-add some_file.wav"); e.command("ao-add /dev/dsp"); e.command("cop-add -efl:100"); e.command("cop-select 1"); e.command("copp-select 1"); e.command("cs-connect"); e.command("start"); while(1) { sleep(1); e.command("engine-status"); if (e.last_string() != "running") break; e.command("get-position"); double curpos = e.last_float(); if (curpos > 15.0) break; e.command("copp-get"); double next_cutoff = cutoff_inc + e.last_float(); e.command_float_arg("copp-set", next_cutoff); } e.command("stop"); e.command("cs-disconnect"); e.command("cop-status"); cerr << "Chain operator status: " << e.last_string() << endl; return(0); }
Returning a list of strings is implemented using two functions: eci_last_string_list_count() returns the number of strings available, and eci_last_string_list_item(int n) returns a pointer (const char*) to the string at index n.
Note! As of ecasound 2.0.1, the C ECI implementation also provides reentrant access to the ECI API. These alternative routines are marked with '_r' postfix.
#include <stdio.h> #include <unistd.h> #include <ecasoundc.h> int main(int argc, char *argv[]) { double cutoff_inc = 500.0; eci_init(); eci_command("cs-add play_chainsetup"); eci_command("c-add 1st_chain"); eci_command("ai-add some_file.wav"); eci_command("ao-add /dev/dsp"); eci_command("cop-add -efl:100"); eci_command("cop-select 1"); eci_command("copp-select 1"); eci_command("cs-connect"); eci_command("start"); while(1) { double curpos, next_cutoff; sleep(1); eci_command("engine-status"); if (strcmp(eci_last_string(), "running") != 0) break; eci_command("get-position"); curpos = eci_last_float(); if (curpos > 15.0) break; eci_command("copp-get"); next_cutoff = cutoff_inc + eci_last_float(); eci_command_float_arg("copp-set", next_cutoff); } eci_command("stop"); eci_command("cs-disconnect"); eci_command("cop-status"); printf("Chain operator status: %s", eci_last_string()); eci_cleanup(); return(0); }
Note! Eric S. Tiedemann has written an alternative Python interface to ECI. You'll find this interface included in the main ecasound packege, in pyecasound/esteci.py. To use this instead of the standard interface, just 'import eci' and you're set! :)
#!/usr/local/bin/python import time from pyeca import * e = ECA_CONTROL_INTERFACE() e.command("cs-add play_chainsetup") e.command("c-add 1st_chain") e.command("ai-add some_file.wav") e.command("ao-add /dev/dsp") e.command("cop-add -efl:100") e.command("cop-select 1") e.command("copp-select 1") e.command("cs-connect") e.command("start") cutoff_inc = 500.0 while 1: time.sleep(1) e.command("engine-status") if e.last_string() != "running": break e.command("get-position") curpos = e.last_float() if curpos > 15: break e.command("copp-get") next_cutoff = cutoff_inc + e.last_float() e.command_float_arg("copp-set", next_cutoff) e.command("stop") e.command("cs-disconnect") e.command("cop-status") print "Chain operator status: ", e.last_string()
Audio::Ecasound was written by Brad Bowman. At the moment this module is not distributed with ecasound. To get the latest version, check the following CPAN link.
eci("cs-add play_chainsetup"); eci("c-add 1st_chain"); eci("ai-add some_file.wav"); eci("ao-add /dev/dsp"); # multiple \n separated commands eci("cop-add -efl:100 # with comments cop-select 1 copp-select 1 cs-connect"); eci("start"); my $cutoff_inc = 500.0; while (1) { sleep(1); last if eci("engine-status") ne "running"; my $curpos = eci("get-position"); last if $curpos > 15; my $next_cutoff = $cutoff_inc + eci("copp-get"); # Optional float argument eci("copp-set", $next_cutoff); } eci("stop"); eci("cs-disconnect"); print "Chain operator status: ", eci("cop-status");
The PHP Ecasound extension was written by Tony Leake. At the moment this module is not distributed with ecasound. The latest version and example scripts, are available from http://www.webwise-data.co.uk/php_audio/php_audio_extension.html.
Implementation of the following: 1. Setup ECI to read audio from file, apply a 100Hz lowpass filter, and send it to the soundcard (/dev/dsp). 2. Every second, check the current position. If the stream has been running for over 15 seconds, exit immediately. Also, every second, increase the lowpass filter's cutoff frequency by 500Hz. 3. Stop the stream (if not already finished) and disconnect the chainsetup. Print chain operator status info <?php $cutoff_inc = 500.0; $curpos=0; $next_cutoff=0; eci_init(); eci_command("cs-add play_chainsetup"); eci_command("c-add 1st_chain"); eci_command("ai-add /tmp/somefile.wav"); eci_command("ao-add /dev/dsp"); eci_command("cop-add -efl:10"); eci_command("cop-select 1"); eci_command("copp-select 1"); eci_command("cs-connect"); eci_command("start"); while(1) { sleep(1); eci_command("engine-status"); if (eci_last_string() !="running"){ break; } eci_command("get-position"); $curpos = eci_last_float(); if ($curpos > 15.0){ break; } eci_command("copp-get"); $next_cutoff = $cutoff_inc + eci_last_float(); eci_command_float_arg("copp-set",$next_cutoff); } eci_command("stop"); eci_command("cs-disconnect"); eci_command("cop-status"); printf("Chain operator status: %s", eci_last_string()); eci_cleanup(); ?>
Here's a few tips what to do if the ECI app you have developed is not working correctly.
This document was generated using the LaTeX2HTML translator Version 2K.1beta (1.48)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -no_math -html_version 3.2,math -short_index -split 2 -link 5 -dir html_ecidoc eci_doc.latex
The translation was initiated by Junichi Uekawa on 2003-10-05