dfb2a60d6298878d3cf24f56af9d273548cdb28f
[blender-staging.git] / intern / audaspace / jack / AUD_JackDevice.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN LGPL LICENSE BLOCK *****
5  *
6  * Copyright 2009 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * AudaSpace is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * ***** END LGPL LICENSE BLOCK *****
24  */
25
26 #include "AUD_Mixer.h"
27 #include "AUD_JackDevice.h"
28 #include "AUD_IReader.h"
29 #include "AUD_Buffer.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 void* AUD_JackDevice::runThread(void* device)
35 {
36         ((AUD_JackDevice*)device)->updateRingBuffers();
37         return NULL;
38 }
39
40 void AUD_JackDevice::updateRingBuffers()
41 {
42         size_t size, temp;
43         unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
44         unsigned int i, j;
45         unsigned int channels = m_specs.channels;
46         sample_t* buffer = m_buffer->getBuffer();
47         float* deinterleave = m_deinterleavebuf->getBuffer();
48
49         pthread_mutex_lock(&m_lock);
50         while(m_valid)
51         {
52                 size = jack_ringbuffer_write_space(m_ringbuffers[0]);
53                 for(i = 1; i < channels; i++)
54                         if((temp = jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
55                                 size = temp;
56
57                 while(size > samplesize)
58                 {
59                         size /= samplesize;
60                         mix((data_t*)buffer, size);
61                         for(i = 0; i < channels; i++)
62                         {
63                                 for(j = 0; j < size; j++)
64                                         deinterleave[i * size + j] = buffer[i + j * channels];
65                                 jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
66                         }
67
68                         size = jack_ringbuffer_write_space(m_ringbuffers[0]);
69                         for(i = 1; i < channels; i++)
70                                 if((temp = jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
71                                         size = temp;
72                 }
73
74                 pthread_cond_wait(&m_condition, &m_lock);
75         }
76         pthread_mutex_unlock(&m_lock);
77 }
78
79 int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
80 {
81         AUD_JackDevice* device = (AUD_JackDevice*)data;
82         unsigned int i;
83         int count = device->m_specs.channels;
84         char* buffer;
85
86         size_t temp;
87         size_t readsamples = jack_ringbuffer_read_space(device->m_ringbuffers[0]);
88         for(i = 1; i < count; i++)
89                 if((temp = jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
90                         readsamples = temp;
91
92         readsamples = AUD_MIN(readsamples / sizeof(float), length);
93
94         for(unsigned int i = 0; i < count; i++)
95         {
96                 buffer = (char*)jack_port_get_buffer(device->m_ports[i], length);
97                 jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
98                 if(readsamples < length)
99                         memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
100         }
101
102         if(pthread_mutex_trylock(&(device->m_lock)) == 0)
103         {
104                 pthread_cond_signal(&(device->m_condition));
105                 pthread_mutex_unlock(&(device->m_lock));
106         }
107
108         return 0;
109 }
110
111 void AUD_JackDevice::jack_shutdown(void *data)
112 {
113         AUD_JackDevice* device = (AUD_JackDevice*)data;
114         device->m_valid = false;
115 }
116
117 AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs, int buffersize)
118 {
119         if(specs.channels == AUD_CHANNELS_INVALID)
120                 specs.channels = AUD_CHANNELS_STEREO;
121
122         // jack uses floats
123         m_specs = specs;
124         m_specs.format = AUD_FORMAT_FLOAT32;
125
126         jack_options_t options = JackNullOption;
127         jack_status_t status;
128
129         // open client
130         m_client = jack_client_open("Blender", options, &status);
131         if(m_client == NULL)
132                 AUD_THROW(AUD_ERROR_JACK);
133
134         // set callbacks
135         jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
136         jack_on_shutdown(m_client, AUD_JackDevice::jack_shutdown, this);
137
138         // register our output channels which are called ports in jack
139         m_ports = new jack_port_t*[m_specs.channels]; AUD_NEW("jack_port")
140
141         try
142         {
143                 char portname[64];
144                 for(int i = 0; i < m_specs.channels; i++)
145                 {
146                         sprintf(portname, "out %d", i+1);
147                         m_ports[i] = jack_port_register(m_client, portname,
148                                                                                         JACK_DEFAULT_AUDIO_TYPE,
149                                                                                         JackPortIsOutput, 0);
150                         if(m_ports[i] == NULL)
151                                 AUD_THROW(AUD_ERROR_JACK);
152                 }
153         }
154         catch(AUD_Exception)
155         {
156                 jack_client_close(m_client);
157                 delete[] m_ports; AUD_DELETE("jack_port")
158                 throw;
159         }
160
161         m_specs.rate = (AUD_SampleRate)jack_get_sample_rate(m_client);
162
163         buffersize *= sizeof(sample_t);
164         m_ringbuffers = new jack_ringbuffer_t*[specs.channels]; AUD_NEW("jack_buffers")
165         for(unsigned int i = 0; i < specs.channels; i++)
166                 m_ringbuffers[i] = jack_ringbuffer_create(buffersize);
167         buffersize *= specs.channels;
168         m_buffer = new AUD_Buffer(buffersize); AUD_NEW("buffer");
169         m_deinterleavebuf = new AUD_Buffer(buffersize); AUD_NEW("buffer");
170
171         create();
172
173         try
174         {
175                 // activate the client
176                 if(jack_activate(m_client))
177                         AUD_THROW(AUD_ERROR_JACK);
178         }
179         catch(AUD_Exception)
180         {
181                 jack_client_close(m_client);
182                 delete[] m_ports; AUD_DELETE("jack_port")
183                 delete m_buffer; AUD_DELETE("buffer");
184                 delete m_deinterleavebuf; AUD_DELETE("buffer");
185                 for(unsigned int i = 0; i < specs.channels; i++)
186                         jack_ringbuffer_free(m_ringbuffers[i]);
187                 delete[] m_ringbuffers; AUD_DELETE("jack_buffers")
188                 destroy();
189                 throw;
190         }
191
192         const char** ports = jack_get_ports(m_client, NULL, NULL,
193                                                                                 JackPortIsPhysical | JackPortIsInput);
194         if(ports != NULL)
195         {
196                 for(int i = 0; i < m_specs.channels && ports[i]; i++)
197                         jack_connect(m_client, jack_port_name(m_ports[i]), ports[i]);
198
199                 free(ports);
200         }
201
202         m_valid = true;
203
204         pthread_mutex_init(&m_lock, NULL);
205         pthread_cond_init(&m_condition, NULL);
206
207         pthread_attr_t attr;
208         pthread_attr_init(&attr);
209         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
210
211         pthread_create(&m_thread, &attr, runThread, this);
212
213         pthread_attr_destroy(&attr);
214 }
215
216 AUD_JackDevice::~AUD_JackDevice()
217 {
218         if(m_valid)
219                 jack_client_close(m_client);
220         m_valid = false;
221
222         delete[] m_ports; AUD_DELETE("jack_port")
223
224         pthread_mutex_lock(&m_lock);
225         pthread_cond_signal(&m_condition);
226         pthread_mutex_unlock(&m_lock);
227         pthread_join(m_thread, NULL);
228
229         pthread_cond_destroy(&m_condition);
230         pthread_mutex_destroy(&m_lock);
231         delete m_buffer; AUD_DELETE("buffer");
232         delete m_deinterleavebuf; AUD_DELETE("buffer");
233         for(unsigned int i = 0; i < m_specs.channels; i++)
234                 jack_ringbuffer_free(m_ringbuffers[i]);
235         delete[] m_ringbuffers; AUD_DELETE("jack_buffers")
236
237         destroy();
238 }
239
240 void AUD_JackDevice::playing(bool playing)
241 {
242         // Do nothing.
243 }