Mercurial > hg > sonic-visualiser
comparison audioio/AudioPortAudioTarget.cpp @ 0:cd5d7ff8ef38
* Reorganising code base. This revision will not compile.
author | Chris Cannam |
---|---|
date | Mon, 31 Jul 2006 12:03:45 +0000 |
parents | |
children | 52409ab73526 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cd5d7ff8ef38 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2006 Chris Cannam. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #ifdef HAVE_PORTAUDIO | |
17 | |
18 #include "AudioPortAudioTarget.h" | |
19 #include "AudioCallbackPlaySource.h" | |
20 | |
21 #include <iostream> | |
22 #include <cassert> | |
23 #include <cmath> | |
24 | |
25 //#define DEBUG_AUDIO_PORT_AUDIO_TARGET 1 | |
26 | |
27 AudioPortAudioTarget::AudioPortAudioTarget(AudioCallbackPlaySource *source) : | |
28 AudioCallbackPlayTarget(source), | |
29 m_stream(0), | |
30 m_bufferSize(0), | |
31 m_sampleRate(0), | |
32 m_latency(0) | |
33 { | |
34 PaError err; | |
35 | |
36 err = Pa_Initialize(); | |
37 if (err != paNoError) { | |
38 std::cerr << "ERROR: AudioPortAudioTarget: Failed to initialize PortAudio" << std::endl; | |
39 return; | |
40 } | |
41 | |
42 m_bufferSize = 1024; | |
43 m_sampleRate = 44100; | |
44 if (m_source && (m_source->getSourceSampleRate() != 0)) { | |
45 m_sampleRate = m_source->getSourceSampleRate(); | |
46 } | |
47 | |
48 m_latency = Pa_GetMinNumBuffers(m_bufferSize, m_sampleRate) * m_bufferSize; | |
49 | |
50 std::cerr << "\n\n\nLATENCY= " << m_latency << std::endl; | |
51 | |
52 err = Pa_OpenDefaultStream(&m_stream, 0, 2, paFloat32, | |
53 m_sampleRate, m_bufferSize, 0, | |
54 processStatic, this); | |
55 | |
56 if (err != paNoError) { | |
57 std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream" << std::endl; | |
58 m_stream = 0; | |
59 Pa_Terminate(); | |
60 return; | |
61 } | |
62 | |
63 err = Pa_StartStream(m_stream); | |
64 | |
65 if (err != paNoError) { | |
66 std::cerr << "ERROR: AudioPortAudioTarget: Failed to start PortAudio stream" << std::endl; | |
67 Pa_CloseStream(m_stream); | |
68 m_stream = 0; | |
69 Pa_Terminate(); | |
70 return; | |
71 } | |
72 | |
73 if (m_source) { | |
74 std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl; | |
75 m_source->setTargetBlockSize(m_bufferSize); | |
76 m_source->setTargetSampleRate(m_sampleRate); | |
77 m_source->setTargetPlayLatency(m_latency); | |
78 } | |
79 } | |
80 | |
81 AudioPortAudioTarget::~AudioPortAudioTarget() | |
82 { | |
83 if (m_stream) { | |
84 PaError err; | |
85 err = Pa_CloseStream(m_stream); | |
86 if (err != paNoError) { | |
87 std::cerr << "ERROR: AudioPortAudioTarget: Failed to close PortAudio stream" << std::endl; | |
88 } | |
89 Pa_Terminate(); | |
90 } | |
91 } | |
92 | |
93 bool | |
94 AudioPortAudioTarget::isOK() const | |
95 { | |
96 return (m_stream != 0); | |
97 } | |
98 | |
99 int | |
100 AudioPortAudioTarget::processStatic(void *input, void *output, | |
101 unsigned long nframes, | |
102 PaTimestamp outTime, void *data) | |
103 { | |
104 return ((AudioPortAudioTarget *)data)->process(input, output, | |
105 nframes, outTime); | |
106 } | |
107 | |
108 void | |
109 AudioPortAudioTarget::sourceModelReplaced() | |
110 { | |
111 m_source->setTargetSampleRate(m_sampleRate); | |
112 } | |
113 | |
114 int | |
115 AudioPortAudioTarget::process(void *inputBuffer, void *outputBuffer, | |
116 unsigned long nframes, | |
117 PaTimestamp) | |
118 { | |
119 #ifdef DEBUG_AUDIO_PORT_AUDIO_TARGET | |
120 std::cout << "AudioPortAudioTarget::process(" << nframes << ")" << std::endl; | |
121 #endif | |
122 | |
123 if (!m_source) return 0; | |
124 | |
125 float *output = (float *)outputBuffer; | |
126 | |
127 assert(nframes <= m_bufferSize); | |
128 | |
129 static float **tmpbuf = 0; | |
130 static size_t tmpbufch = 0; | |
131 static size_t tmpbufsz = 0; | |
132 | |
133 size_t sourceChannels = m_source->getSourceChannelCount(); | |
134 | |
135 // Because we offer pan, we always want at least 2 channels | |
136 if (sourceChannels < 2) sourceChannels = 2; | |
137 | |
138 if (!tmpbuf || tmpbufch != sourceChannels || tmpbufsz < m_bufferSize) { | |
139 | |
140 if (tmpbuf) { | |
141 for (size_t i = 0; i < tmpbufch; ++i) { | |
142 delete[] tmpbuf[i]; | |
143 } | |
144 delete[] tmpbuf; | |
145 } | |
146 | |
147 tmpbufch = sourceChannels; | |
148 tmpbufsz = m_bufferSize; | |
149 tmpbuf = new float *[tmpbufch]; | |
150 | |
151 for (size_t i = 0; i < tmpbufch; ++i) { | |
152 tmpbuf[i] = new float[tmpbufsz]; | |
153 } | |
154 } | |
155 | |
156 m_source->getSourceSamples(nframes, tmpbuf); | |
157 | |
158 float peakLeft = 0.0, peakRight = 0.0; | |
159 | |
160 for (size_t ch = 0; ch < 2; ++ch) { | |
161 | |
162 float peak = 0.0; | |
163 | |
164 if (ch < sourceChannels) { | |
165 | |
166 // PortAudio samples are interleaved | |
167 for (size_t i = 0; i < nframes; ++i) { | |
168 output[i * 2 + ch] = tmpbuf[ch][i] * m_outputGain; | |
169 float sample = fabsf(output[i * 2 + ch]); | |
170 if (sample > peak) peak = sample; | |
171 } | |
172 | |
173 } else if (ch == 1 && sourceChannels == 1) { | |
174 | |
175 for (size_t i = 0; i < nframes; ++i) { | |
176 output[i * 2 + ch] = tmpbuf[0][i] * m_outputGain; | |
177 float sample = fabsf(output[i * 2 + ch]); | |
178 if (sample > peak) peak = sample; | |
179 } | |
180 | |
181 } else { | |
182 for (size_t i = 0; i < nframes; ++i) { | |
183 output[i * 2 + ch] = 0; | |
184 } | |
185 } | |
186 | |
187 if (ch == 0) peakLeft = peak; | |
188 if (ch > 0 || sourceChannels == 1) peakRight = peak; | |
189 } | |
190 | |
191 m_source->setOutputLevels(peakLeft, peakRight); | |
192 | |
193 return 0; | |
194 } | |
195 | |
196 #ifdef INCLUDE_MOCFILES | |
197 #include "AudioPortAudioTarget.moc.cpp" | |
198 #endif | |
199 | |
200 #endif /* HAVE_PORTAUDIO */ | |
201 |