wfview/audiohandler.h

259 wiersze
6.1 KiB
C++

#ifndef AUDIOHANDLER_H
#define AUDIOHANDLER_H
#include <QObject>
#include <QByteArray>
#include <QMutex>
#include <QtEndian>
#include <QtMath>
#if defined(RTAUDIO)
#include "rtaudio/RtAudio.h"
#elif defined (PORTAUDIO)
#include "portaudio.h"
#error "PORTAUDIO is not currently supported"
#else
#include <QAudioOutput>
#include <QAudioFormat>
#include <QAudioDeviceInfo>
#include <QAudioInput>
#include <QIODevice>
#endif
typedef signed short MY_TYPE;
#define FORMAT RTAUDIO_SINT16
#define SCALE 32767.0
#define LOG100 4.60517018599
#include <QThread>
#include <QTimer>
#include <QTime>
#include <QMap>
#include "resampler/speex_resampler.h"
#include "ring/ring.h"
#include "audiotaper.h"
#include <QDebug>
// Plugin includes:
#include <stdlib.h>
#include <stdio.h>
#ifdef Q_OS_WIN
#include "dlfcn/dlfcn.h"
#include "ladspa/ladspa.h"
#else
#include <dlfcn.h>
#include <ladspa.h>
#endif
//#define BUFFER_SIZE (32*1024)
#define INTERNAL_SAMPLE_RATE 48000
#define MULAW_BIAS 33
#define MULAW_MAX 0x1fff
struct audioPacket {
quint32 seq;
QTime time;
quint16 sent;
QByteArray data;
};
struct audioSetup {
QString name;
quint8 bits;
quint8 radioChan;
quint16 samplerate;
quint16 latency;
quint8 codec;
bool ulaw;
bool isinput;
#if defined(RTAUDIO)
int port;
#elif defined(PORTAUDIO)
#else
QAudioDeviceInfo port;
#endif
quint8 resampleQuality;
unsigned char localAFgain;
};
// For QtMultimedia, use a native QIODevice
#if !defined(PORTAUDIO) && !defined(RTAUDIO)
class audioHandler : public QIODevice
#else
class audioHandler : public QObject
#endif
{
Q_OBJECT
public:
audioHandler(QObject* parent = 0);
~audioHandler();
int getLatency();
void enablePluginOutput(bool enable);
#if !defined (RTAUDIO) && !defined(PORTAUDIO)
bool setDevice(QAudioDeviceInfo deviceInfo);
void start();
void flush();
void stop();
qint64 bytesAvailable() const;
bool isSequential() const;
#endif
void getNextAudioChunk(QByteArray &data);
public slots:
bool init(audioSetup setup);
void changeLatency(const quint16 newSize);
void setVolume(unsigned char volume);
void incomingAudio(const audioPacket data);
private slots:
#if !defined (RTAUDIO) && !defined(PORTAUDIO)
void notified();
void stateChanged(QAudio::State state);
#endif
signals:
void audioMessage(QString message);
void sendLatency(quint16 newSize);
void haveAudioData(const QByteArray& data);
private:
#if defined(RTAUDIO)
int readData(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status);
static int staticRead(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void* userData) {
return static_cast<audioHandler*>(userData)->readData(outputBuffer, inputBuffer, nFrames, streamTime, status);
}
int writeData(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status);
static int staticWrite(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void* userData) {
return static_cast<audioHandler*>(userData)->writeData(outputBuffer, inputBuffer, nFrames, streamTime, status);
}
#elif defined(PORTAUDIO)
#else
qint64 readData(char* data, qint64 nBytes);
qint64 writeData(const char* data, qint64 nBytes);
#endif
void reinit();
bool isInitialized=false;
bool isReady = false;
#if defined(RTAUDIO)
RtAudio* audio = Q_NULLPTR;
int audioDevice = 0;
RtAudio::StreamParameters aParams;
RtAudio::StreamOptions options;
RtAudio::DeviceInfo info;
#elif defined(PORTAUDIO)
#else
QAudioOutput* audioOutput=Q_NULLPTR;
QAudioInput* audioInput=Q_NULLPTR;
QAudioFormat format;
QAudioDeviceInfo deviceInfo;
#endif
SpeexResamplerState* resampler = Q_NULLPTR;
bool isUlaw;
quint16 audioLatency;
bool isInput; // Used to determine whether input or output audio
unsigned int chunkSize;
bool chunkAvailable;
quint32 lastSeq;
quint16 radioSampleRate;
quint16 nativeSampleRate=0;
quint8 radioSampleBits;
quint8 radioChannels;
QMap<quint32, audioPacket>audioBuffer;
unsigned int ratioNum;
unsigned int ratioDen;
// --- Plugin support:
QMutex pluginMutex;
//QByteArray pluginOutputQBA;
uint16_t *pluginOutput16bitInterlaced;
uint16_t SAMPLE_RATE;
uint16_t BUF_SIZE;
const LADSPA_Descriptor * psDescriptor;
LADSPA_Descriptor_Function pfDescriptorFunction;
LADSPA_Handle handle;
// Works:
// char *pcPluginFilename = (char*)"amp.so";
// char *pcPluginLabel = (char*)"amp_stereo";
// Testing:
#ifdef Q_OS_WIN
char*
pcPluginFilename = (char*)"dyson_compress_1403.dll";
#else
char*
pcPluginFilename = (char*)"dyson_compress_1403.so";
#endif
char *pcPluginLabel = (char*)"dysonCompress";
int inBufferIndex = 0;
int outBufferIndex = 0;
long lInputPortIndex = -1;
long lOutputPortIndex = -1;
LADSPA_Data *pInBuffer[2];
LADSPA_Data *pOutBuffer[2];
// Plugin controls:
LADSPA_Data control;
LADSPA_Data pre_control = 0.2f;
LADSPA_Data controls[15]; // 15 controls
bool pluginOutputEnable = true;
void setupLADSP();
void runPlugin();
// from load.c:
void *dlopenLADSPA(const char *pcFilename, int iFlag);
void *loadLADSPAPluginLibrary(const char * pcPluginFilename);
void unloadLADSPAPluginLibrary(void * pvLADSPAPluginLibrary);
const LADSPA_Descriptor *
findLADSPAPluginDescriptor(void * pvLADSPAPluginLibrary,
const char * pcPluginLibraryFilename,
const char * pcPluginLabel);
// --- End plugin items
wilt::Ring<audioPacket> *ringBuf=Q_NULLPTR;
volatile bool ready = false;
audioPacket tempBuf;
quint16 currentLatency;
qreal volume=1.0;
int devChannels;
audioSetup setup;
};
#endif // AUDIOHANDLER_H