comparison audioio/AudioPortAudioTarget.cpp @ 101:89a689720ee9 spectrogram-cache-rejig

* Merge from trunk
author Chris Cannam
date Wed, 27 Feb 2008 11:59:42 +0000
parents bf1a53489ccc
children
comparison
equal deleted inserted replaced
59:bf1a53489ccc 101:89a689720ee9
27 AudioPortAudioTarget::AudioPortAudioTarget(AudioCallbackPlaySource *source) : 27 AudioPortAudioTarget::AudioPortAudioTarget(AudioCallbackPlaySource *source) :
28 AudioCallbackPlayTarget(source), 28 AudioCallbackPlayTarget(source),
29 m_stream(0), 29 m_stream(0),
30 m_bufferSize(0), 30 m_bufferSize(0),
31 m_sampleRate(0), 31 m_sampleRate(0),
32 m_latency(0) 32 m_latency(0),
33 m_done(false)
33 { 34 {
34 PaError err; 35 PaError err;
35 36
36 #ifdef DEBUG_AUDIO_PORT_AUDIO_TARGET 37 #ifdef DEBUG_AUDIO_PORT_AUDIO_TARGET
37 #ifdef HAVE_PORTAUDIO_V18 38 #ifdef HAVE_PORTAUDIO_V18
45 if (err != paNoError) { 46 if (err != paNoError) {
46 std::cerr << "ERROR: AudioPortAudioTarget: Failed to initialize PortAudio: " << Pa_GetErrorText(err) << std::endl; 47 std::cerr << "ERROR: AudioPortAudioTarget: Failed to initialize PortAudio: " << Pa_GetErrorText(err) << std::endl;
47 return; 48 return;
48 } 49 }
49 50
50 m_bufferSize = 1024; 51 m_bufferSize = 2048;
51 m_sampleRate = 44100; 52 m_sampleRate = 44100;
52 if (m_source && (m_source->getSourceSampleRate() != 0)) { 53 if (m_source && (m_source->getSourceSampleRate() != 0)) {
53 m_sampleRate = m_source->getSourceSampleRate(); 54 m_sampleRate = m_source->getSourceSampleRate();
54 } 55 }
55 56
60 #ifdef HAVE_PORTAUDIO_V18 61 #ifdef HAVE_PORTAUDIO_V18
61 err = Pa_OpenDefaultStream(&m_stream, 0, 2, paFloat32, 62 err = Pa_OpenDefaultStream(&m_stream, 0, 2, paFloat32,
62 m_sampleRate, m_bufferSize, 0, 63 m_sampleRate, m_bufferSize, 0,
63 processStatic, this); 64 processStatic, this);
64 #else 65 #else
65 err = Pa_OpenDefaultStream(&m_stream, 0, 2, paFloat32, 66 PaStreamParameters op;
66 m_sampleRate, m_bufferSize, 67 op.device = Pa_GetDefaultOutputDevice();
67 processStatic, this); 68 op.channelCount = 2;
69 op.sampleFormat = paFloat32;
70 op.suggestedLatency = 0.2;
71 op.hostApiSpecificStreamInfo = 0;
72 err = Pa_OpenStream(&m_stream, 0, &op, m_sampleRate,
73 paFramesPerBufferUnspecified,
74 paNoFlag, processStatic, this);
68 #endif 75 #endif
76
77 #ifndef HAVE_PORTAUDIO_V18
78 if (err != paNoError) {
79
80 std::cerr << "WARNING: AudioPortAudioTarget: Failed to open PortAudio stream with default frames per buffer, trying again with fixed frames per buffer..." << std::endl;
81
82 err = Pa_OpenStream(&m_stream, 0, &op, m_sampleRate,
83 1024,
84 paNoFlag, processStatic, this);
85 m_bufferSize = 1024;
86 }
87 #endif
69 88
70 if (err != paNoError) { 89 if (err != paNoError) {
71 std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream: " << Pa_GetErrorText(err) << std::endl; 90 std::cerr << "ERROR: AudioPortAudioTarget: Failed to open PortAudio stream: " << Pa_GetErrorText(err) << std::endl;
72 m_stream = 0; 91 m_stream = 0;
73 Pa_Terminate(); 92 Pa_Terminate();
75 } 94 }
76 95
77 #ifndef HAVE_PORTAUDIO_V18 96 #ifndef HAVE_PORTAUDIO_V18
78 const PaStreamInfo *info = Pa_GetStreamInfo(m_stream); 97 const PaStreamInfo *info = Pa_GetStreamInfo(m_stream);
79 m_latency = int(info->outputLatency * m_sampleRate + 0.001); 98 m_latency = int(info->outputLatency * m_sampleRate + 0.001);
99 if (m_bufferSize < m_latency) m_bufferSize = m_latency;
80 #endif 100 #endif
81 101
82 std::cerr << "PortAudio latency = " << m_latency << " frames" << std::endl; 102 std::cerr << "PortAudio latency = " << m_latency << " frames" << std::endl;
83 103
84 err = Pa_StartStream(m_stream); 104 err = Pa_StartStream(m_stream);
91 return; 111 return;
92 } 112 }
93 113
94 if (m_source) { 114 if (m_source) {
95 std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl; 115 std::cerr << "AudioPortAudioTarget: block size " << m_bufferSize << std::endl;
96 m_source->setTargetBlockSize(m_bufferSize); 116 m_source->setTarget(this, m_bufferSize);
97 m_source->setTargetSampleRate(m_sampleRate); 117 m_source->setTargetSampleRate(m_sampleRate);
98 m_source->setTargetPlayLatency(m_latency); 118 m_source->setTargetPlayLatency(m_latency);
99 } 119 }
100 120
101 #ifdef DEBUG_PORT_AUDIO_TARGET 121 #ifdef DEBUG_PORT_AUDIO_TARGET
103 #endif 123 #endif
104 } 124 }
105 125
106 AudioPortAudioTarget::~AudioPortAudioTarget() 126 AudioPortAudioTarget::~AudioPortAudioTarget()
107 { 127 {
128 std::cerr << "AudioPortAudioTarget::~AudioPortAudioTarget()" << std::endl;
129
130 if (m_source) {
131 m_source->setTarget(0, m_bufferSize);
132 }
133
134 shutdown();
135
108 if (m_stream) { 136 if (m_stream) {
137
138 std::cerr << "closing stream" << std::endl;
139
109 PaError err; 140 PaError err;
110 err = Pa_CloseStream(m_stream); 141 err = Pa_CloseStream(m_stream);
111 if (err != paNoError) { 142 if (err != paNoError) {
112 std::cerr << "ERROR: AudioPortAudioTarget: Failed to close PortAudio stream: " << Pa_GetErrorText(err) << std::endl; 143 std::cerr << "ERROR: AudioPortAudioTarget: Failed to close PortAudio stream: " << Pa_GetErrorText(err) << std::endl;
113 } 144 }
145
146 std::cerr << "terminating" << std::endl;
147
114 err = Pa_Terminate(); 148 err = Pa_Terminate();
115 if (err != paNoError) { 149 if (err != paNoError) {
116 std::cerr << "ERROR: AudioPortAudioTarget: Failed to terminate PortAudio: " << Pa_GetErrorText(err) << std::endl; 150 std::cerr << "ERROR: AudioPortAudioTarget: Failed to terminate PortAudio: " << Pa_GetErrorText(err) << std::endl;
117 } 151 }
118 } 152 }
153
154 m_stream = 0;
155
156 std::cerr << "AudioPortAudioTarget::~AudioPortAudioTarget() done" << std::endl;
157 }
158
159 void
160 AudioPortAudioTarget::shutdown()
161 {
162 m_done = true;
119 } 163 }
120 164
121 bool 165 bool
122 AudioPortAudioTarget::isOK() const 166 AudioPortAudioTarget::isOK() const
123 { 167 {
124 return (m_stream != 0); 168 return (m_stream != 0);
169 }
170
171 double
172 AudioPortAudioTarget::getCurrentTime() const
173 {
174 if (!m_stream) return 0.0;
175 else return Pa_GetStreamTime(m_stream);
125 } 176 }
126 177
127 #ifdef HAVE_PORTAUDIO_V18 178 #ifdef HAVE_PORTAUDIO_V18
128 int 179 int
129 AudioPortAudioTarget::processStatic(void *input, void *output, 180 AudioPortAudioTarget::processStatic(void *input, void *output,
167 { 218 {
168 #ifdef DEBUG_AUDIO_PORT_AUDIO_TARGET 219 #ifdef DEBUG_AUDIO_PORT_AUDIO_TARGET
169 std::cout << "AudioPortAudioTarget::process(" << nframes << ")" << std::endl; 220 std::cout << "AudioPortAudioTarget::process(" << nframes << ")" << std::endl;
170 #endif 221 #endif
171 222
172 if (!m_source) return 0; 223 if (!m_source || m_done) return 0;
173 224
174 float *output = (float *)outputBuffer; 225 float *output = (float *)outputBuffer;
175 226
176 assert(nframes <= m_bufferSize); 227 assert(nframes <= m_bufferSize);
177 228