1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/******************************************************************************\
* Copyright (c) 2004-2020
*
* Author(s):
* Volker Fischer
*
******************************************************************************
*
* 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; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
\******************************************************************************/
#pragma once
#ifndef JACK_REPLACES_ASIO // these headers are not available in Windows OS
# include <unistd.h>
# include <sys/ioctl.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <QThread>
#include <string.h>
#include "util.h"
#include "soundbase.h"
#include "global.h"
#if WITH_SOUND
# include <jack/jack.h>
# include <jack/midiport.h>
#endif
/* Definitions ****************************************************************/
#define NUM_IN_OUT_CHANNELS 2 // always stereo
// the number of periods is critical for latency
#define NUM_PERIOD_BLOCKS_IN 2
#define NUM_PERIOD_BLOCKS_OUT 1
#define MAX_SND_BUF_IN 200
#define MAX_SND_BUF_OUT 200
/* Classes ********************************************************************/
#if WITH_SOUND
class CSound : public CSoundBase
{
public:
CSound ( void (*fpNewProcessCallback) ( CVector<short>& psData, void* arg ),
void* arg,
const QString& strMIDISetup,
const bool bNoAutoJackConnect,
const QString& strJackClientName ) :
CSoundBase ( "Jack", fpNewProcessCallback, arg, strMIDISetup ),
iJACKBufferSizeMono ( 0 ), bJackWasShutDown ( false ), fInOutLatencyMs ( 0.0f ) { OpenJack ( bNoAutoJackConnect, strJackClientName.toLocal8Bit().data() ); }
virtual ~CSound() { CloseJack(); }
virtual int Init ( const int iNewPrefMonoBufferSize );
virtual void Start();
virtual void Stop();
virtual float GetInOutLatencyMs() { return fInOutLatencyMs; }
// these variables should be protected but cannot since we want
// to access them from the callback function
CVector<short> vecsTmpAudioSndCrdStereo;
int iJACKBufferSizeMono;
int iJACKBufferSizeStero;
bool bJackWasShutDown;
jack_port_t* input_port_left;
jack_port_t* input_port_right;
jack_port_t* output_port_left;
jack_port_t* output_port_right;
jack_port_t* input_port_midi;
protected:
void OpenJack ( const bool bNoAutoJackConnect,
const char* jackClientName );
void CloseJack();
// callbacks
static int process ( jack_nframes_t nframes, void* arg );
static int bufferSizeCallback ( jack_nframes_t, void *arg );
static void shutdownCallback ( void* );
jack_client_t* pJackClient;
float fInOutLatencyMs;
};
#else
// no sound -> dummy class definition
#include "server.h"
class CSound : public CSoundBase
{
Q_OBJECT
public:
CSound ( void (*fpNewProcessCallback) ( CVector<short>& psData, void* pParg ),
void* pParg,
const QString& strMIDISetup,
const bool ,
const QString& ) :
CSoundBase ( "nosound", fpNewProcessCallback, pParg, strMIDISetup ),
HighPrecisionTimer ( true ) { HighPrecisionTimer.Start();
QObject::connect ( &HighPrecisionTimer, &CHighPrecisionTimer::timeout,
this, &CSound::OnTimer ); }
virtual ~CSound() {}
virtual int Init ( const int iNewPrefMonoBufferSize ) { CSoundBase::Init ( iNewPrefMonoBufferSize );
vecsTemp.Init ( 2 * iNewPrefMonoBufferSize );
return iNewPrefMonoBufferSize; }
CHighPrecisionTimer HighPrecisionTimer;
CVector<short> vecsTemp;
public slots:
void OnTimer() { vecsTemp.Reset ( 0 ); if ( IsRunning() ) { ProcessCallback ( vecsTemp ); } }
};
#endif // WITH_SOUND
|