annotate audioio/AudioPortAudioTarget.cpp @ 10:b6dc944128da

* Add basics of MIDI file import. Doesn't actually create the model yet. * Add rewind to start / ffwd to end. * Make zoom constraint default to sqrt(2) type if no constraint set
author Chris Cannam
date Thu, 09 Feb 2006 18:01:52 +0000
parents df5923e33d01
children ba31fa322f93
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@2 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #ifdef HAVE_PORTAUDIO
Chris@0 11
Chris@0 12 #include "AudioPortAudioTarget.h"
Chris@0 13 #include "AudioCallbackPlaySource.h"
Chris@0 14
Chris@0 15 #include <iostream>
Chris@0 16 #include <cassert>
Chris@0 17 #include <cmath>
Chris@0 18
Chris@0 19 //#define DEBUG_AUDIO_PORT_AUDIO_TARGET 1
Chris@0 20
Chris@0 21 AudioPortAudioTarget::AudioPortAudioTarget(AudioCallbackPlaySource *source) :
Chris@0 22 AudioCallbackPlayTarget(source),
Chris@0 23 m_stream(0),
Chris@0 24 m_bufferSize(0),
Chris@0 25 m_sampleRate(0),
Chris@0 26 m_latency(0)
Chris@0 27 {
Chris@0 28 PaError err;
Chris@0 29
Chris@0 30 err = Pa_Initialize();
Chris@0 31 if (err != paNoError) {
Chris@0 32 std::cerr << "ERROR: AudioPortAudioTarget: Failed to initialize PortAudio" << std::endl;
Chris@0 33 return;
Chris@0 34 }
Chris@0 35
Chris@0 36 m_bufferSize = 1024;
Chris@0 37 m_sampleRate = 44100;
Chris@0 38 if (m_source && (m_source->getSourceSampleRate() != 0)) {
Chris@0 39 m_sampleRate = m_source->getSourceSampleRate();
Chris@0 40 }
Chris@0 41
Chris@0 42 m_latency = Pa_GetMinNumBuffers(m_bufferSize, m_sampleRate) * m_bufferSize;
Chris@0 43
Chris@0 44 err = Pa_OpenDefaultStream(&m_stream, 0, 2, paFloat32,
Chris@0 45 m_sampleRate, m_bufferSize, 0,
Chris@0 46 processStatic, this);
Chris@0 47
Chris@0 48 if (err != paNoError) {
Chris@0 49 std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream" << std::endl;
Chris@0 50 m_stream = 0;
Chris@0 51 Pa_Terminate();
Chris@0 52 return;
Chris@0 53 }
Chris@0 54
Chris@0 55 err = Pa_StartStream(m_stream);
Chris@0 56
Chris@0 57 if (err != paNoError) {
Chris@0 58 std::cerr << "ERROR: AudioPortAudioTarget: Failed to start PortAudio stream" << std::endl;
Chris@0 59 Pa_CloseStream(m_stream);
Chris@0 60 m_stream = 0;
Chris@0 61 Pa_Terminate();
Chris@0 62 return;
Chris@0 63 }
Chris@0 64
Chris@0 65 if (m_source) {
Chris@0 66 std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl;
Chris@0 67 m_source->setTargetBlockSize(m_bufferSize);
Chris@0 68 m_source->setTargetSampleRate(m_sampleRate);
Chris@0 69 m_source->setTargetPlayLatency(m_latency);
Chris@0 70 }
Chris@0 71 }
Chris@0 72
Chris@0 73 AudioPortAudioTarget::~AudioPortAudioTarget()
Chris@0 74 {
Chris@0 75 if (m_stream) {
Chris@0 76 PaError err;
Chris@0 77 err = Pa_CloseStream(m_stream);
Chris@0 78 if (err != paNoError) {
Chris@0 79 std::cerr << "ERROR: AudioPortAudioTarget: Failed to close PortAudio stream" << std::endl;
Chris@0 80 }
Chris@0 81 Pa_Terminate();
Chris@0 82 }
Chris@0 83 }
Chris@0 84
Chris@0 85 bool
Chris@0 86 AudioPortAudioTarget::isOK() const
Chris@0 87 {
Chris@0 88 return (m_stream != 0);
Chris@0 89 }
Chris@0 90
Chris@0 91 int
Chris@0 92 AudioPortAudioTarget::processStatic(void *input, void *output,
Chris@0 93 unsigned long nframes,
Chris@0 94 PaTimestamp outTime, void *data)
Chris@0 95 {
Chris@0 96 return ((AudioPortAudioTarget *)data)->process(input, output,
Chris@0 97 nframes, outTime);
Chris@0 98 }
Chris@0 99
Chris@0 100 void
Chris@0 101 AudioPortAudioTarget::sourceModelReplaced()
Chris@0 102 {
Chris@0 103 m_source->setTargetSampleRate(m_sampleRate);
Chris@0 104 }
Chris@0 105
Chris@0 106 int
Chris@0 107 AudioPortAudioTarget::process(void *inputBuffer, void *outputBuffer,
Chris@0 108 unsigned long nframes,
Chris@0 109 PaTimestamp)
Chris@0 110 {
Chris@0 111 #ifdef DEBUG_AUDIO_PORT_AUDIO_TARGET
Chris@0 112 std::cout << "AudioPortAudioTarget::process(" << nframes << ")" << std::endl;
Chris@0 113 #endif
Chris@0 114
Chris@0 115 if (!m_source) return 0;
Chris@0 116
Chris@0 117 float *output = (float *)outputBuffer;
Chris@0 118
Chris@0 119 assert(nframes <= m_bufferSize);
Chris@0 120
Chris@0 121 static float **tmpbuf = 0;
Chris@0 122 static size_t tmpbufch = 0;
Chris@0 123 static size_t tmpbufsz = 0;
Chris@0 124
Chris@0 125 size_t sourceChannels = m_source->getSourceChannelCount();
Chris@0 126
Chris@0 127 if (!tmpbuf || tmpbufch != sourceChannels || tmpbufsz < m_bufferSize) {
Chris@0 128
Chris@0 129 if (tmpbuf) {
Chris@0 130 for (size_t i = 0; i < tmpbufch; ++i) {
Chris@0 131 delete[] tmpbuf[i];
Chris@0 132 }
Chris@0 133 delete[] tmpbuf;
Chris@0 134 }
Chris@0 135
Chris@0 136 tmpbufch = sourceChannels;
Chris@0 137 tmpbufsz = m_bufferSize;
Chris@0 138 tmpbuf = new float *[tmpbufch];
Chris@0 139
Chris@0 140 for (size_t i = 0; i < tmpbufch; ++i) {
Chris@0 141 tmpbuf[i] = new float[tmpbufsz];
Chris@0 142 }
Chris@0 143 }
Chris@0 144
Chris@0 145 m_source->getSourceSamples(nframes, tmpbuf);
Chris@0 146
Chris@0 147 float peakLeft = 0.0, peakRight = 0.0;
Chris@0 148
Chris@0 149 for (size_t ch = 0; ch < 2; ++ch) {
Chris@0 150
Chris@0 151 float peak = 0.0;
Chris@0 152
Chris@0 153 if (ch < sourceChannels) {
Chris@0 154
Chris@0 155 // PortAudio samples are interleaved
Chris@0 156 for (size_t i = 0; i < nframes; ++i) {
Chris@0 157 output[i * 2 + ch] = tmpbuf[ch][i] * m_outputGain;
Chris@0 158 float sample = fabsf(output[i * 2 + ch]);
Chris@0 159 if (sample > peak) peak = sample;
Chris@0 160 }
Chris@0 161
Chris@0 162 } else if (ch == 1 && sourceChannels == 1) {
Chris@0 163
Chris@0 164 for (size_t i = 0; i < nframes; ++i) {
Chris@0 165 output[i * 2 + ch] = tmpbuf[0][i] * m_outputGain;
Chris@0 166 float sample = fabsf(output[i * 2 + ch]);
Chris@0 167 if (sample > peak) peak = sample;
Chris@0 168 }
Chris@0 169
Chris@0 170 } else {
Chris@0 171 for (size_t i = 0; i < nframes; ++i) {
Chris@0 172 output[i * 2 + ch] = 0;
Chris@0 173 }
Chris@0 174 }
Chris@0 175
Chris@0 176 if (ch == 0) peakLeft = peak;
Chris@0 177 if (ch > 0 || sourceChannels == 1) peakRight = peak;
Chris@0 178 }
Chris@0 179
Chris@0 180 m_source->setOutputLevels(peakLeft, peakRight);
Chris@0 181
Chris@0 182 return 0;
Chris@0 183 }
Chris@0 184
Chris@0 185 #ifdef INCLUDE_MOCFILES
Chris@0 186 #include "AudioPortAudioTarget.moc.cpp"
Chris@0 187 #endif
Chris@0 188
Chris@0 189 #endif /* HAVE_PORTAUDIO */
Chris@0 190