annotate audioio/AudioPortAudioSource.cpp @ 17:3cbd40805795 tip

Remove obsolete stuff from README
author Chris Cannam
date Tue, 03 Dec 2013 16:33:08 +0000
parents a6020bf991cd
children
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 #ifdef HAVE_PORTAUDIO
cannam@0 4
cannam@0 5 #include "AudioPortAudioSource.h"
cannam@0 6 #include "AudioCallbackRecordTarget.h"
cannam@0 7
cannam@0 8 #include <iostream>
cannam@0 9 #include <cassert>
cannam@0 10 #include <cmath>
cannam@0 11
cannam@0 12 //#define DEBUG_AUDIO_PORT_AUDIO_SOURCE 1
cannam@0 13
cannam@0 14 AudioPortAudioSource::AudioPortAudioSource(AudioCallbackRecordTarget *target) :
cannam@0 15 AudioCallbackRecordSource(target),
cannam@0 16 m_stream(0),
cannam@0 17 m_bufferSize(0),
cannam@0 18 m_sampleRate(0),
cannam@0 19 m_latency(0)
cannam@0 20 {
cannam@0 21 PaError err;
cannam@0 22
cannam@0 23 err = Pa_Initialize();
cannam@0 24 if (err != paNoError) {
cannam@0 25 std::cerr << "ERROR: AudioPortAudioSource: Failed to initialize PortAudio" << std::endl;
cannam@0 26 return;
cannam@0 27 }
cannam@0 28
cannam@0 29 m_bufferSize = 1024;
cannam@0 30 m_sampleRate = 44100;
cannam@0 31 if (m_target && (m_target->getPreferredSampleRate() != 0)) {
cannam@0 32 m_sampleRate = m_target->getPreferredSampleRate();
cannam@0 33 }
cannam@0 34
cannam@0 35 m_latency = Pa_GetMinNumBuffers(m_bufferSize, m_sampleRate) * m_bufferSize;
cannam@0 36
cannam@0 37 err = Pa_OpenDefaultStream(&m_stream, m_target->getChannelCount(),
cannam@0 38 0, paFloat32,
cannam@0 39 m_sampleRate, m_bufferSize, 0,
cannam@0 40 processStatic, this);
cannam@0 41
cannam@0 42 if (err != paNoError) {
cannam@0 43 std::cerr << "ERROR: AudioPortAudioSource: Failed to open PortAudio stream" << std::endl;
cannam@0 44 m_stream = 0;
cannam@0 45 Pa_Terminate();
cannam@0 46 return;
cannam@0 47 }
cannam@0 48
cannam@0 49 err = Pa_StartStream(m_stream);
cannam@0 50
cannam@0 51 if (err != paNoError) {
cannam@0 52 std::cerr << "ERROR: AudioPortAudioSource: Failed to start PortAudio stream" << std::endl;
cannam@0 53 Pa_CloseStream(m_stream);
cannam@0 54 m_stream = 0;
cannam@0 55 Pa_Terminate();
cannam@0 56 return;
cannam@0 57 }
cannam@0 58
cannam@0 59 if (m_target) {
cannam@0 60 std::cerr << "AudioPortAudioSource: block size " << m_bufferSize << std::endl;
cannam@0 61 m_target->setSourceBlockSize(m_bufferSize);
cannam@0 62 m_target->setSourceSampleRate(m_sampleRate);
cannam@0 63 m_target->setSourceRecordLatency(m_latency);
cannam@0 64 }
cannam@0 65 }
cannam@0 66
cannam@0 67 AudioPortAudioSource::~AudioPortAudioSource()
cannam@0 68 {
cannam@0 69 if (m_stream) {
cannam@0 70 PaError err;
cannam@0 71 err = Pa_CloseStream(m_stream);
cannam@0 72 if (err != paNoError) {
cannam@0 73 std::cerr << "ERROR: AudioPortAudioSource: Failed to close PortAudio stream" << std::endl;
cannam@0 74 }
cannam@0 75 Pa_Terminate();
cannam@0 76 }
cannam@0 77 }
cannam@0 78
cannam@0 79 bool
cannam@0 80 AudioPortAudioSource::isOK() const
cannam@0 81 {
cannam@0 82 return (m_stream != 0);
cannam@0 83 }
cannam@0 84
cannam@0 85 int
cannam@0 86 AudioPortAudioSource::processStatic(void *input, void *output,
cannam@0 87 unsigned long nframes,
cannam@0 88 PaTimestamp outTime, void *data)
cannam@0 89 {
cannam@0 90 return ((AudioPortAudioSource *)data)->process(input, output,
cannam@0 91 nframes, outTime);
cannam@0 92 }
cannam@0 93
cannam@0 94 int
cannam@0 95 AudioPortAudioSource::process(void *inputBuffer,
cannam@0 96 void *outputBuffer,
cannam@0 97 unsigned long nframes,
cannam@0 98 PaTimestamp)
cannam@0 99 {
cannam@0 100 #ifdef DEBUG_AUDIO_PORT_AUDIO_SOURCE
cannam@0 101 std::cout << "AudioPortAudioSource::process(" << nframes << ")" << std::endl;
cannam@0 102 #endif
cannam@0 103
cannam@0 104 if (!m_target) return 0;
cannam@0 105
cannam@0 106 float *input = (float *)inputBuffer;
cannam@0 107
cannam@0 108 assert(nframes <= m_bufferSize);
cannam@0 109
cannam@0 110 static float **tmpbuf = 0;
cannam@0 111 static size_t tmpbufch = 0;
cannam@0 112 static size_t tmpbufsz = 0;
cannam@0 113
cannam@0 114 size_t channels = m_target->getChannelCount();
cannam@0 115
cannam@0 116 if (!tmpbuf || tmpbufch != channels || tmpbufsz < m_bufferSize) {
cannam@0 117
cannam@0 118 if (tmpbuf) {
cannam@0 119 for (size_t i = 0; i < tmpbufch; ++i) {
cannam@0 120 delete[] tmpbuf[i];
cannam@0 121 }
cannam@0 122 delete[] tmpbuf;
cannam@0 123 }
cannam@0 124
cannam@0 125 tmpbufch = channels;
cannam@0 126 tmpbufsz = m_bufferSize;
cannam@0 127 tmpbuf = new float *[tmpbufch];
cannam@0 128
cannam@0 129 for (size_t i = 0; i < tmpbufch; ++i) {
cannam@0 130 tmpbuf[i] = new float[tmpbufsz];
cannam@0 131 }
cannam@0 132 }
cannam@0 133
cannam@0 134 float peakLeft = 0.0, peakRight = 0.0;
cannam@0 135
cannam@0 136 for (size_t ch = 0; ch < 2; ++ch) {
cannam@0 137
cannam@0 138 float peak = 0.0;
cannam@0 139
cannam@0 140 if (ch < channels) {
cannam@0 141
cannam@0 142 // PortAudio samples are interleaved
cannam@0 143 for (size_t i = 0; i < nframes; ++i) {
cannam@0 144 tmpbuf[ch][i] = input[i * 2 + ch];
cannam@0 145 float sample = fabsf(input[i * 2 + ch]);
cannam@0 146 if (sample > peak) peak = sample;
cannam@0 147 }
cannam@0 148
cannam@0 149 } else if (ch == 1 && channels == 1) {
cannam@0 150
cannam@0 151 for (size_t i = 0; i < nframes; ++i) {
cannam@0 152 tmpbuf[0][i] = input[i * 2 + ch];
cannam@0 153 float sample = fabsf(input[i * 2 + ch]);
cannam@0 154 if (sample > peak) peak = sample;
cannam@0 155 }
cannam@0 156
cannam@0 157 } else {
cannam@0 158 for (size_t i = 0; i < nframes; ++i) {
cannam@0 159 tmpbuf[ch][i] = 0;
cannam@0 160 }
cannam@0 161 }
cannam@0 162
cannam@0 163 if (ch == 0) peakLeft = peak;
cannam@0 164 if (ch > 0 || channels == 1) peakRight = peak;
cannam@0 165 }
cannam@0 166
cannam@0 167 m_target->putSamples(nframes, tmpbuf);
cannam@0 168 m_target->setInputLevels(peakLeft, peakRight);
cannam@0 169
cannam@0 170 return 0;
cannam@0 171 }
cannam@0 172
cannam@0 173 #endif /* HAVE_PORTAUDIO */
cannam@0 174