diff --git a/plugins/singerbot/Makefile.am b/plugins/singerbot/Makefile.am deleted file mode 100644 index fd428490d..000000000 --- a/plugins/singerbot/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -AUTOMAKE_OPTIONS = foreign 1.4 - - -INCLUDES = -I/usr/include/festival -I/usr/include/speech_tools \ - -I$(top_srcdir)/include -I$(top_srcdir)/src/gui -I. - - -CXXFLAGS += -Wno-non-template-friend - -AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="singerbot" - - -%.moc: ./%.h - $(MOC) -o $@ $< - - -MOC_FILES = ./singerbot.moc - -BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h -EMBEDDED_RESOURCES = $(wildcard *png) - -./embedded_resources.h: $(EMBEDDED_RESOURCES) - $(BIN2RES) $(EMBEDDED_RESOURCES) > $@ - -EXTRA_DIST = $(EMBEDDED_RESOURCES) - - -CLEANFILES = $(MOC_FILES) ./embedded_resources.h - - - -pkglib_LTLIBRARIES = libsingerbot.la - -libsingerbot_la_SOURCES = singerbot.cpp singerbot.h file.h - -$(libsingerbot_la_SOURCES): ./embedded_resources.h - -pkglib_PROGRAMS = singerbot_proxy -singerbot_proxy_SOURCES = singerbot_proxy.cpp -singerbot_proxy_LDFLAGS = -lFestival -lestools -lestbase -lesd -lncurses -lrt diff --git a/plugins/singerbot/artwork.png b/plugins/singerbot/artwork.png deleted file mode 100644 index b5e87153d..000000000 Binary files a/plugins/singerbot/artwork.png and /dev/null differ diff --git a/plugins/singerbot/file.h b/plugins/singerbot/file.h deleted file mode 100644 index 17b0e5312..000000000 --- a/plugins/singerbot/file.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * file.h - file descriptor wrapper - * - * Copyright (c) 2007 Javier Serrano Polo - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#ifndef _FILE_H -#define _FILE_H - - -#include -#include - - -class File -{ -public: - File( int _fd ) : - m_fd( _fd ) - { - } - virtual ~File() - { - close( m_fd ); - } - - template - ssize_t read( T * _i, int _n = 1 ) - { - return( ::read( m_fd, _i, _n * sizeof( T ) ) ); - } - - template - ssize_t write( const T * _i, int _n = 1 ) - { - return( ::write( m_fd, _i, _n * sizeof( T ) ) ); - } - - off_t rewind( void ) - { - return( lseek( m_fd, 0, SEEK_SET ) ); - } - - -private: - const int m_fd; - -} ; - - - - -#endif diff --git a/plugins/singerbot/logo.png b/plugins/singerbot/logo.png deleted file mode 100644 index 72b710afe..000000000 Binary files a/plugins/singerbot/logo.png and /dev/null differ diff --git a/plugins/singerbot/singerbot.cpp b/plugins/singerbot/singerbot.cpp deleted file mode 100644 index 719c3a775..000000000 --- a/plugins/singerbot/singerbot.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/* - * singerbot.cpp - a singing bot instrument plugin - * - * Copyright (c) 2007 Javier Serrano Polo - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#include "singerbot.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "engine.h" -#include "file.h" -#include "instrument_track.h" -#include "note_play_handle.h" -#include "pattern.h" -#include "song.h" - -#undef SINGLE_SOURCE_COMPILE -#include "embed.cpp" - -#include "singerbot.moc" - - -extern "C" -{ - -plugin::descriptor singerbot_plugin_descriptor = -{ - STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ), - "SingerBot", - QT_TRANSLATE_NOOP( "pluginBrowser", - "Singer bot to add some basic vocals" ), - "Javier Serrano Polo ", - 0x0100, - plugin::Instrument, - new pluginPixmapLoader( "logo" ), - NULL -} ; - - -// neccessary for getting instance out of shared lib -plugin * lmms_plugin_main( model *, void * _data ) -{ - return( new singerBot( static_cast( _data ) ) ); -} - -} - - - - -singerBot::singerBot( instrumentTrack * _track ) : - instrument( _track, &singerbot_plugin_descriptor ) -{ - printf("singerBot constructor begin...\n"); fflush(stdout); - - // Create a unique suffix for the /dev/shm device file names - static int suffix_index = 0; - m_file_suffix = '.' + QString::number( getpid() ) + '.' - + QString::number( suffix_index++, 16 ); - - // This creates a (file) device in /dev/shm called lmms_singerbot.[pid].[suffix_index] - int fd = shm_open( addSuffix( "/lmms_singerbot" ), - O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR ); - m_shm = new File( fd ); - - // This creates a (file) device in /dev/shm called sem.lmms_singerbot_s1.[pid].[suffix_index] - m_handle_semaphore = sem_open( addSuffix( "/lmms_singerbot_s1" ), - O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0 ); - - // This creates a (file) device in /dev/shm called sem.lmms_singerbot_s2.[pid].[suffix_index] - m_synth_semaphore = sem_open( addSuffix( "/lmms_singerbot_s2" ), - O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0 ); - - pid_t cpid = fork(); - if( cpid == -1 ) - { - perror( "fork" ); - exit( EXIT_FAILURE ); - } - else if( cpid == 0 ) - { - sem_close( m_handle_semaphore ); - sem_close( m_synth_semaphore ); - - QString proxy_exec = configManager::inst()->pluginDir() + - QDir::separator() + - "singerbot_proxy"; - execlp( proxy_exec.toAscii().constData(), - proxy_exec.toAscii().constData(), - m_file_suffix.toAscii().constData(), - NULL ); - exit( EXIT_FAILURE ); - } - - sem_wait( m_handle_semaphore ); - - // Set a default text string, but do not emit the dataChanged signal - setPlainText( "Hello world", FALSE ); - -} - - - - -singerBot::~singerBot() -{ - m_shm->rewind(); - float stop = -1.0; - m_shm->write( &stop ); - - sem_post( m_synth_semaphore ); - wait( NULL ); - - sem_close( m_handle_semaphore ); - sem_close( m_synth_semaphore ); - sem_unlink( addSuffix( "/lmms_singerbot_s1" ) ); - sem_unlink( addSuffix( "/lmms_singerbot_s2" ) ); - - delete m_shm; - shm_unlink( addSuffix( "/lmms_singerbot" ) ); - -} - - - - -pluginView * singerBot::instantiateView( QWidget * _parent ) -{ - return( new singerBotView( this, _parent ) ); -} - - - - -void singerBot::playNote( notePlayHandle * _n, bool, - sampleFrame * _working_buf ) -{ - printf("singerBot::playNote begin...\n"); fflush(stdout); - - const fpp_t frames = _n->framesLeftForCurrentPeriod(); - - if( !_n->m_pluginData ) - { - createWave( _n ); - } - handle_data * hdata = (handle_data *)_n->m_pluginData; - - if( hdata->remaining_frames <= 0 ) - { - return; - } - - play( _working_buf, hdata, frames ); - getInstrumentTrack()->processAudioBuffer( _working_buf, frames, _n ); - - printf("singerBot::playNote end...\n"); fflush(stdout); -} - - - - -void singerBot::deleteNotePluginData( notePlayHandle * _n ) -{ - handle_data * hdata = (handle_data *)_n->m_pluginData; - delete[] hdata->wave; - src_delete( hdata->resampling_state ); - delete hdata; -} - - - - -void singerBot::saveSettings( QDomDocument & _doc, QDomElement & _this ) -{ - QDomElement element = _doc.createElement( "lyrics" ); - _this.appendChild( element ); - - QDomCDATASection ds = _doc.createCDATASection( m_plain_text ); - element.appendChild( ds ); -} - - - - -void singerBot::loadSettings( const QDomElement & _this ) -{ - QString saved_lyrics = _this.namedItem( "lyrics" ).toElement().text() ; - - // TODO: What if the load fails? - // if (!failed) - // { - setPlainText( saved_lyrics ); - // } - -} - - - - -QString singerBot::nodeName( void ) const -{ - return( singerbot_plugin_descriptor.name ); -} - - - - -void singerBot::setPlainText( const QString & _plain_text, bool _emitDataChanged ) -{ - m_plain_text = _plain_text; - - if (_emitDataChanged) - { - // m_plain_text changed so send out notification - emit ( dataChanged() ); - } - - m_words_dirty = TRUE; -} - - - - -const QString & singerBot::getPlainText() -{ - return m_plain_text; -} - - - - -void singerBot::createWave( notePlayHandle * _n ) -{ - printf("singerBot::createWave begin...\n"); fflush(stdout); - - handle_data * hdata = new handle_data; - _n->m_pluginData = hdata; - hdata->wave = NULL; - hdata->remaining_frames = 0; - hdata->resampling_state = NULL; - - if( m_words_dirty ) - { - m_words = m_plain_text.simplified().toLower().split( ' ' ); - - m_words_dirty = FALSE; - } - - if( m_words.empty() ) - { - return; - } - - printf("_n->frequency = %f\n", _n->frequency() ); fflush(stdout); - - hdata->frequency = _n->frequency(); - hdata->duration = _n->length() > 0 ? - _n->length() * 60.0f * DefaultBeatsPerTact - / 64.0f / engine::getSong()->getTempo() : - 0; - int word_index = _n->patternIndex() % m_words.size(); - hdata->text = m_words[word_index].toAscii().constData(); - - // Debugging only - showHandleData( hdata ); - - synth_send( hdata ); - synth_read( hdata ); - - if( !hdata->wave ) - { - return; - } - - int error; - hdata->resampling_state = src_new( SRC_LINEAR, 1, &error ); - if( !hdata->resampling_state ) - { - printf( "%s: src_new() error: %s\n", __FILE__, - src_strerror( error ) ); - } - - hdata->resampling_data.end_of_input = 0; - hdata->remaining_frames = hdata->num_samples; - - printf("singerBot::createWave end...\n"); fflush(stdout); -} - - - - -void singerBot::play( sampleFrame * _ab, handle_data * _hdata, - const fpp_t _frames ) -{ - printf("singerBot::play begin...\n"); fflush(stdout); - - const f_cnt_t offset = _hdata->num_samples - _hdata->remaining_frames; - - const double ratio = engine::getMixer()->processingSampleRate() - / (double)_hdata->sample_rate; - - const f_cnt_t margin = 2; - f_cnt_t fragment_size = (f_cnt_t)( _frames / ratio ) + margin; - - sample_t * sample_fragment = new sample_t[fragment_size]; - - if( fragment_size <= _hdata->remaining_frames ) - { - for( f_cnt_t frame = 0; frame < fragment_size; ++frame ) - { - sample_fragment[frame] = _hdata->wave[offset + frame] - / OUTPUT_SAMPLE_MULTIPLIER; - } - } - else - { - for( f_cnt_t frame = 0; frame < _hdata->remaining_frames; - ++frame ) - { - sample_fragment[frame] = _hdata->wave[offset + frame] - / OUTPUT_SAMPLE_MULTIPLIER; - } - memset( sample_fragment + _hdata->remaining_frames, 0, - ( fragment_size - _hdata->remaining_frames ) - * sizeof( sample_t ) ); - } - - sample_t * data = new sample_t[_frames]; - - _hdata->resampling_data.data_in = sample_fragment; - _hdata->resampling_data.data_out = data; - _hdata->resampling_data.input_frames = fragment_size; - _hdata->resampling_data.output_frames = _frames; - _hdata->resampling_data.src_ratio = ratio; - int error = src_process( _hdata->resampling_state, - &_hdata->resampling_data ); - if( error ) - { - printf( "%s: error while resampling: %s\n", __FILE__, - src_strerror( error ) ); - } - if( _hdata->resampling_data.output_frames_gen != _frames ) - { - printf( "%s: not enough frames: %ld / %d\n", __FILE__, - _hdata->resampling_data.output_frames_gen, _frames ); - } - _hdata->remaining_frames -= _hdata->resampling_data.input_frames_used; - - for( f_cnt_t frame = 0; frame < _frames; ++frame ) - { - for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) - { - _ab[frame][chnl] = data[frame]; - } - } - - delete[] sample_fragment; - delete[] data; - - printf("singerBot::play end...\n"); fflush(stdout); -} - - - - -void singerBot::synth_send( handle_data * _hdata ) -{ - printf("singerBot::synth_send begin...\n"); fflush(stdout); - - m_shm->rewind(); - m_shm->write( &_hdata->frequency ); - m_shm->write( &_hdata->duration ); - Uint8 len = strlen( _hdata->text ); - m_shm->write( &len ); - m_shm->write( _hdata->text, len ); - - sem_post( m_synth_semaphore ); - - printf("singerBot::synth_send end...\n"); fflush(stdout); -} - - - - -void singerBot::synth_read( handle_data * _hdata ) -{ - printf("singerBot::synth_read begin...\n"); fflush(stdout); - - sem_wait( m_handle_semaphore ); - - m_shm->rewind(); - m_shm->read( &_hdata->num_samples ); - if( !_hdata->num_samples ) - { - return; - } - m_shm->read( &_hdata->sample_rate ); - _hdata->wave = new short[_hdata->num_samples]; - m_shm->read( _hdata->wave, _hdata->num_samples ); - - printf("singerBot::synth_read end...\n"); fflush(stdout); -} - - - - -const char * singerBot::addSuffix( const char * _s ) -{ - return( QString( _s + m_file_suffix ).toAscii().constData() ); -} - - - -// For debugging only -void singerBot::showHandleData( handle_data * _hdata ) -{ - printf("Show Handle Data:\n"); - printf("wave = %u\n", (unsigned int)_hdata->wave); - printf("num_samples = %d\n", _hdata->num_samples); - printf("sample_rate = %d\n", _hdata->sample_rate); - printf("remaining_frames = %d\n", _hdata->remaining_frames); - printf("frequency = %f\n", _hdata->frequency); - printf("duration = %f\n", _hdata->duration); - //const char * text; - //SRC_STATE * resampling_state; - //SRC_DATA resampling_data; - - fflush(stdout); -} - - -// ******** The View ********* - -singerBotView::singerBotView( instrument * _instrument, - QWidget * _parent ) : - instrumentView( _instrument, _parent ) -{ - setAutoFillBackground( TRUE ); - QPalette pal; - pal.setBrush( backgroundRole(), - PLUGIN_NAME::getIconPixmap( "artwork" ) ); - setPalette( pal ); - - QVBoxLayout * vbox = new QVBoxLayout( this ); - vbox->setMargin( 10 ); - vbox->setSpacing( 0 ); - vbox->addSpacing( 45 ); - - m_lyrics = new QTextEdit( this ); - m_lyrics->setAutoFillBackground( TRUE ); - pal.setColor( m_lyrics->backgroundRole(), QColor( 64, 64, 64 ) ); - m_lyrics->setPalette( pal ); - - // Connect the QTextEdit textChanged signal to the viewTextChanged slot - connect( m_lyrics, SIGNAL( textChanged( void ) ), - this, SLOT( viewTextChanged( void ) ) ); - - // Need to set the view's text the same as the model, so just run the handler - // that would have run if we had gotten dataChanged() signal from the model - modelTextChanged(); - - vbox->addWidget( m_lyrics ); - - // Connect the model dataChanged event to the view's handler - // (see example from audio_file_processor.cpp line 585) - connect( castModel(), SIGNAL( dataChanged() ), - this, SLOT( modelTextChanged() ) ); - -} - - - - -// This slot is connected to the QTextEdit textChanged singal -void singerBotView::viewTextChanged( void ) -{ - QString modelText = castModel()->getPlainText(); - - // If the model text is already the same then stop updating - // (otherwise there would be a infinite loop of model -> view -> model -> etc - if (m_lyrics->toPlainText() != modelText) - { - // Call the model to set the new text that changed via UI - castModel()->setPlainText( m_lyrics->toPlainText() ); - } - -} - - - -void singerBotView::modelTextChanged( void ) -{ - // Set the view's text the same as the model - m_lyrics->setText( castModel()->getPlainText() ); -} - - - - -singerBotView::~singerBotView() -{ -} diff --git a/plugins/singerbot/singerbot.h b/plugins/singerbot/singerbot.h deleted file mode 100644 index 165492908..000000000 --- a/plugins/singerbot/singerbot.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * singerbot.h - declaration of class singerBot, a singing bot instrument plugin - * - * Copyright (c) 2007 Javier Serrano Polo - * Copyright (c) 2008 Tobias Doerffel - * - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#ifndef _SINGERBOT_H -#define _SINGERBOT_H - -#include "lmmsconfig.h" - -#ifndef LMMS_USE_3RDPARTY_LIBSRC -#include -#else -#include "src/3rdparty/samplerate/samplerate.h" -#endif - -#include - -#include "instrument.h" -#include "instrument_view.h" -#include "mixer.h" - - -class File; -class QTextEdit; -class sampleBuffer; -class singerBotView; - -class singerBot : public instrument -{ - Q_OBJECT -public: - singerBot( instrumentTrack * _track ); - virtual ~singerBot(); - - virtual void playNote( notePlayHandle * _n, bool _try_parallelizing, - sampleFrame * _working_buf ); - virtual void deleteNotePluginData( notePlayHandle * _n ); - - - virtual void saveSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - - virtual QString nodeName( void ) const; - - virtual pluginView * instantiateView( QWidget * _parent ); - - void setPlainText( const QString & _plain_text, - bool _emitDataChanged = TRUE ); - const QString & getPlainText(); - -private: - typedef struct - { - short * wave; - int num_samples; - int sample_rate; - f_cnt_t remaining_frames; - float frequency; - float duration; - const char * text; - SRC_STATE * resampling_state; - SRC_DATA resampling_data; - } handle_data; - - - QString m_file_suffix; - - File * m_shm; - sem_t * m_handle_semaphore; - sem_t * m_synth_semaphore; - - // m_plain_text is the model, and m_words is parsed list of the words in m_plain_text - QString m_plain_text; - QStringList m_words; - bool m_words_dirty; - - void createWave( notePlayHandle * _n ); - void play( sampleFrame * _ab, handle_data * _hdata, - const fpp_t _frames ); - - void synth_send( handle_data * _hdata ); - void synth_read( handle_data * _hdata ); - - const char * addSuffix( const char * _s ); - void showHandleData( handle_data * _hdata ); - - friend class singerBotView; - -} ; - - - - -class singerBotView : public instrumentView -{ - Q_OBJECT -public: - singerBotView( instrument * _instrument, QWidget * _parent ); - virtual ~singerBotView(); - -public slots: - void viewTextChanged( void ); - void modelTextChanged( void ); - -private: - QTextEdit * m_lyrics; - -} ; - - -#endif diff --git a/plugins/singerbot/singerbot_proxy.cpp b/plugins/singerbot/singerbot_proxy.cpp deleted file mode 100644 index 791f10243..000000000 --- a/plugins/singerbot/singerbot_proxy.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - * singerbot_proxy.cpp - separate process to deal with Festival - * - * Copyright (c) 2007 Javier Serrano Polo - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#include -#include -#include -#include - -#include "file.h" - -#undef HAVE_CONFIG_H -#include - - -static File * s_shm; -static sem_t * s_handle_semaphore; -static sem_t * s_synth_semaphore; - - -static void run( void ); -static EST_Wave * text_to_wave( float _frequency, float _duration, - const char * _text ); -static EST_Wave * get_wave( const char * _name ); - - - - -int main( int argc, char * * argv ) -{ - string resource = "/lmms_singerbot"; - resource += argv[1]; - int fd = shm_open( resource.c_str(), O_RDWR, S_IRUSR | S_IWUSR ); - s_shm = new File( fd ); - - resource = "/lmms_singerbot_s1"; - resource += argv[1]; - s_handle_semaphore = sem_open( resource.c_str(), 0 ); - - resource = "/lmms_singerbot_s2"; - resource += argv[1]; - s_synth_semaphore = sem_open( resource.c_str(), 0 ); - - sem_post( s_handle_semaphore ); - - run(); - - sem_close( s_handle_semaphore ); - sem_close( s_synth_semaphore ); - - delete s_shm; - - return( EXIT_SUCCESS ); -} - - - - -void run( void ) -{ - const int load_init_files = 1; - festival_initialize( load_init_files, FESTIVAL_HEAP_SIZE ); - - festival_eval_command( - "(define get_segment" - " (lambda (utt) (begin" - " (Initialize utt)" - " (Text utt)" - " (Token_POS utt)" - " (Token utt)" - " (POS utt)" - " (Phrasify utt)" - " (Word utt)" - " ))" - ")" ); - - festival_eval_command( - "(Parameter.set 'Int_Method 'DuffInt)" ); - festival_eval_command( - "(Parameter.set 'Int_Target_Method Int_Targets_Default)" ); - - for( ; ; ) - { - sem_wait( s_synth_semaphore ); - - float frequency; - float duration; - - s_shm->rewind(); - s_shm->read( &frequency ); - if( frequency == -1.0f ) - { - break; - } - s_shm->read( &duration ); - unsigned char len; - s_shm->read( &len ); - char * text = new char[len + 1]; - s_shm->read( text, len ); - text[len] = '\0'; - - EST_Wave * wave = text_to_wave( frequency, duration, text ); - if( !wave ) - { - // Damaged SIOD environment? Retrying... - wave = text_to_wave( frequency, duration, text ); - if( !wave ) - { - printf( "Unsupported frequency?\n" ); - } - } - - s_shm->rewind(); - int num_samples = wave ? wave->num_samples() : 0; - s_shm->write( &num_samples ); - if( num_samples ) - { - int sample_rate = wave->sample_rate(); - s_shm->write( &sample_rate ); - } - - for( int i = 0; i < num_samples; ++i ) - { - short sample = wave->a( i ); - s_shm->write( &sample ); - } - delete wave; - - sem_post( s_handle_semaphore ); - } -} - - - - -EST_Wave * text_to_wave( float _frequency, float _duration, const char * _text ) -{ - char command[80]; - sprintf( command, - "(set! duffint_params '((start %f) (end %f)))", _frequency, - _frequency ); - festival_eval_command( command ); - festival_eval_command( - "(Parameter.set 'Duration_Stretch 1)" ); - - sprintf( command, - "(set! total_time (parse-number %f))", _duration ); - festival_eval_command( command ); - festival_eval_command( - "(set! word " + quote_string( _text, "\"", "\\", 1 ) + ")" ); - if( festival_eval_command( - "(begin" - " (set! my_utt (eval (list 'Utterance 'Text word)))" - " (get_segment my_utt)" - " (if (equal? (length (utt.relation.leafs my_utt 'Segment)) 1)" - " (begin (set! my_utt (eval " - " (list 'Utterance 'Text (string-append word \" \" word))))" - " (get_segment my_utt)" - " ))" - " (Pauses my_utt)" - " (item.delete (utt.relation.first my_utt 'Segment))" - " (item.delete (utt.relation.last my_utt 'Segment))" - " (Intonation my_utt)" - " (PostLex my_utt)" - " (Duration my_utt)" - " (if (not (equal? total_time 0)) (begin" - " (set! utt_time" - " (item.feat (utt.relation.last my_utt 'Segment) 'end))" - " (Parameter.set 'Duration_Stretch (/ total_time utt_time))" - " (Duration my_utt)" - " ))" - " (Int_Targets my_utt)" - ")" ) - - && festival_eval_command( - " (Wave_Synth my_utt)" ) ) - { - return( get_wave( "my_utt" ) ); - } - - return( NULL ); -} - - - - -EST_Wave * get_wave( const char * _name ) -{ - LISP lutt = siod_get_lval( _name, NULL ); - if( !utterance_p( lutt ) ) - { - return( NULL ); - } - - EST_Relation * r = utterance( lutt )->relation( "Wave" ); - - //TODO: This check is useless. The error is fatal. - if ( !r || !r->head() ) - { - return( NULL ); - } - - return( new EST_Wave( *wave( r->head()->f( "wave" ) ) ) ); -}