Mercurial > hg > svapp
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 |