/* * Copyright (C) 2002 - David W. Durham * * This file is part of ReZound, an audio editing application. * * ReZound 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. * * ReZound 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "CJACKSoundPlayer.h" #ifdef ENABLE_JACK #include #include #include #include #include #include #include "settings.h" #include "AFrontendHooks.h" #include "AStatusComm.h" /* * Ask the mailing list about the hangup signal and I probably want to catch it and not die * * Further testing needs to be done about the jackd process dieing while ReZound is running and what to do in that situation * */ unsigned CJACKSoundPlayer::hack_sampleRate=44100; CJACKSoundPlayer::CJACKSoundPlayer() : ASoundPlayer(), initialized(false), client(NULL), tempBuffer(1) { for(unsigned t=0;t inputPortNames; const char **ports=jack_get_ports(client,NULL,NULL,JackPortIsInput); while(ports && *ports) inputPortNames.push_back(*(ports++)); ports-=inputPortNames.size(); free(ports); // connect the ports for(unsigned t=0;tpromptForJACKPort(_("Choose Port for Output Channel ")+istring(t+1),inputPortNames); } const string portName=gJACKOutputPortNames[t]; if(jack_connect(client,jack_port_name(output_ports[t]),portName.c_str())) { Warning(_("Cannot connect to JACK port, ")+portName+_(", please choose a different one")); gJACKOutputPortNames[t]=""; goto askAgain; } } ASoundPlayer::initialize(); initialized=true; } catch(...) { deinitialize(); throw; } } else throw runtime_error(string(__func__)+" -- already initialized"); } void CJACKSoundPlayer::deinitialize() { ASoundPlayer::deinitialize(); if(client!=NULL) { jack_deactivate(client); for(unsigned t=0;ttempBuffer; that->mixSoundPlayerChannels(gDesiredOutputChannelCount,tempBuffer,(unsigned)nframes); // copy interlaced tempBuffer to 'out[0..n-1]' (and converting the sample type as needed) const unsigned channelCount=that->devices[0].channelCount; for(unsigned i=0;ioutput_ports[i],nframes); const sample_t *tt=tempBuffer+i; for(unsigned t=0;t(*tt); } } catch(exception &e) { fprintf(stderr,"exception caught in play callback: %s\n",e.what()); // ??? I used to abort() here, but I should probably count so something a // little more careful like count the exceptions and after 25, abort so // that it doesn't endlessly happen, but doesn't die on the off-chance that // something might happen that can be recovered from ... change all the // other's too (including Recorder classes) } catch(...) { fprintf(stderr,"unknown exception caught in play callback\n"); } return 0; } int CJACKSoundPlayer::sampleRateChanged(jack_nframes_t nframes,void *arg) { CJACKSoundPlayer *that=(CJACKSoundPlayer *)arg; that->devices[0].sampleRate=nframes; // ??? this is simply always device zero for now CJACKSoundPlayer::hack_sampleRate=nframes; return 0; } void CJACKSoundPlayer::jackShutdown(void *arg) { } #endif // ENABLE_JACK