| 95 | // static snd_pcm_sframes_t snd_pcm_ffado_write(snd_pcm_ioplug_t *io, |
---|
| 96 | // const snd_pcm_channel_area_t *areas, |
---|
| 97 | // snd_pcm_uframes_t offset, |
---|
| 98 | // snd_pcm_uframes_t size) |
---|
| 99 | // { |
---|
| 100 | // PRINT_FUNCTION_ENTRY; |
---|
| 101 | // snd_pcm_ffado_t *ffado = (snd_pcm_ffado_t *)io->private_data; |
---|
| 102 | // IpcRingBuffer::eResult res; |
---|
| 103 | // unsigned int i; |
---|
| 104 | // |
---|
| 105 | // do { |
---|
| 106 | // uint32_t *audiobuffers_raw; |
---|
| 107 | // res = ffado->buffer->requestBlockForWrite((void**) &audiobuffers_raw); // pointer voodoo |
---|
| 108 | // if(res == IpcRingBuffer::eR_OK) { |
---|
| 109 | // memset(audiobuffers_raw, 0, ffado->channels * ffado->period * 4); |
---|
| 110 | // for (i = 0; i < ffado->channels; i++) { |
---|
| 111 | // uint32_t *alsa_data_ptr = (uint32_t *)((char *)areas[i].addr + (areas[i].step * offset / 8)); |
---|
| 112 | // uint32_t *ffado_data_ptr = audiobuffers_raw + i*ffado->period; |
---|
| 113 | // memcpy(ffado_data_ptr, alsa_data_ptr, ffado->period * 4); |
---|
| 114 | // } |
---|
| 115 | // // release the block |
---|
| 116 | // res = ffado->buffer->releaseBlockForWrite(); |
---|
| 117 | // if(res != IpcRingBuffer::eR_OK) { |
---|
| 118 | // debugOutput(DEBUG_LEVEL_NORMAL, "PBK: error committing memory block\n"); |
---|
| 119 | // break; |
---|
| 120 | // } |
---|
| 121 | // } else if(res != IpcRingBuffer::eR_Again) { |
---|
| 122 | // debugOutput(DEBUG_LEVEL_NORMAL, "PBK: error getting memory block\n"); |
---|
| 123 | // } |
---|
| 124 | // } while (res == IpcRingBuffer::eR_Again); |
---|
| 125 | // |
---|
| 126 | // ffado->hw_ptr += ffado->period; |
---|
| 127 | // ffado->hw_ptr %= io->buffer_size; |
---|
| 128 | // |
---|
| 129 | // if(size != ffado->period) { |
---|
| 130 | // debugWarning("size %d, period %d, offset %d\n", size, ffado->period, offset); |
---|
| 131 | // } else { |
---|
| 132 | // debugOutput(DEBUG_LEVEL_NORMAL, "size %d, period %d, offset %d\n", size, ffado->period, offset); |
---|
| 133 | // } |
---|
| 134 | // |
---|
| 135 | // if(res == IpcRingBuffer::eR_OK) { |
---|
| 136 | // return ffado->period; |
---|
| 137 | // } else { |
---|
| 138 | // debugOutput(DEBUG_LEVEL_NORMAL, "error happened\n"); |
---|
| 139 | // return -1; |
---|
| 140 | // } |
---|
| 141 | // } |
---|
| 142 | // |
---|
| 143 | // static snd_pcm_sframes_t snd_pcm_ffado_read(snd_pcm_ioplug_t *io, |
---|
| 144 | // const snd_pcm_channel_area_t *areas, |
---|
| 145 | // snd_pcm_uframes_t offset, |
---|
| 146 | // snd_pcm_uframes_t size) |
---|
| 147 | // { |
---|
| 148 | // PRINT_FUNCTION_ENTRY; |
---|
| 149 | // snd_pcm_ffado_t *ffado = (snd_pcm_ffado_t *)io->private_data; |
---|
| 150 | // IpcRingBuffer::eResult res; |
---|
| 151 | // unsigned int i; |
---|
| 152 | // |
---|
| 153 | // do { |
---|
| 154 | // uint32_t *audiobuffers_raw; |
---|
| 155 | // res = ffado->buffer->requestBlockForRead((void**) &audiobuffers_raw); // pointer voodoo |
---|
| 156 | // if(res == IpcRingBuffer::eR_OK) { |
---|
| 157 | // for (i = 0; i < ffado->channels; i++) { |
---|
| 158 | // uint32_t *alsa_data_ptr = (uint32_t *)((char *)areas[i].addr + (areas[i].step * offset / 8)); |
---|
| 159 | // uint32_t *ffado_data_ptr = audiobuffers_raw + i*ffado->period; |
---|
| 160 | // memcpy(alsa_data_ptr, ffado_data_ptr, ffado->period * 4); |
---|
| 161 | // } |
---|
| 162 | // // release the block |
---|
| 163 | // res = ffado->buffer->releaseBlockForRead(); |
---|
| 164 | // if(res != IpcRingBuffer::eR_OK) { |
---|
| 165 | // debugOutput(DEBUG_LEVEL_NORMAL, "CAP: error committing memory block\n"); |
---|
| 166 | // break; |
---|
| 167 | // } |
---|
| 168 | // } else if(res != IpcRingBuffer::eR_Again) { |
---|
| 169 | // debugOutput(DEBUG_LEVEL_NORMAL, "CAP: error getting memory block\n"); |
---|
| 170 | // } |
---|
| 171 | // } while (res == IpcRingBuffer::eR_Again); |
---|
| 172 | // |
---|
| 173 | // ffado->hw_ptr += ffado->period; |
---|
| 174 | // ffado->hw_ptr %= io->buffer_size; |
---|
| 175 | // |
---|
| 176 | // if(res == IpcRingBuffer::eR_OK) { |
---|
| 177 | // return ffado->period; |
---|
| 178 | // } else { |
---|
| 179 | // debugOutput(DEBUG_LEVEL_NORMAL, "error happened\n"); |
---|
| 180 | // return -1; |
---|
| 181 | // } |
---|
| 182 | // } |
---|
| 183 | |
---|
| 184 | // if (io->state != SND_PCM_STATE_RUNNING) { |
---|
| 185 | // if (io->stream == SND_PCM_STREAM_PLAYBACK) { |
---|
| 186 | // for (channel = 0; channel < io->channels; channel++) |
---|
| 187 | // snd_pcm_area_silence(&jack->areas[channel], 0, nframes, io->format); |
---|
| 188 | // return 0; |
---|
| 189 | // } |
---|
| 190 | // } |
---|
| 191 | // |
---|
| 192 | // areas = snd_pcm_ioplug_mmap_areas(io); |
---|
| 193 | // |
---|
| 194 | // while (xfer < nframes) { |
---|
| 195 | // snd_pcm_uframes_t frames = nframes - xfer; |
---|
| 196 | // snd_pcm_uframes_t offset = jack->hw_ptr; |
---|
| 197 | // snd_pcm_uframes_t cont = io->buffer_size - offset; |
---|
| 198 | // |
---|
| 199 | // if (cont < frames) |
---|
| 200 | // frames = cont; |
---|
| 201 | // |
---|
| 202 | // for (channel = 0; channel < io->channels; channel++) { |
---|
| 203 | // if (io->stream == SND_PCM_STREAM_PLAYBACK) |
---|
| 204 | // snd_pcm_area_copy(&jack->areas[channel], xfer, &areas[channel], offset, frames, io->format); |
---|
| 205 | // else |
---|
| 206 | // snd_pcm_area_copy(&areas[channel], offset, &jack->areas[channel], xfer, frames, io->format); |
---|
| 207 | // } |
---|
| 208 | // |
---|
| 209 | // jack->hw_ptr += frames; |
---|
| 210 | // jack->hw_ptr %= io->buffer_size; |
---|
| 211 | // xfer += frames; |
---|
| 212 | // } |
---|
| 213 | // |
---|
| 214 | // write(jack->fd, buf, 1); /* for polling */ |
---|
| 215 | |
---|
120 | | do { |
---|
121 | | uint32_t *audiobuffers_raw; |
---|
122 | | res = ffado->buffer->requestBlockForWrite((void**) &audiobuffers_raw); // pointer voodoo |
---|
123 | | if(res == IpcRingBuffer::eR_OK) { |
---|
124 | | memset(audiobuffers_raw, 0, ffado->channels * ffado->period * 4); |
---|
125 | | for (i = 0; i < ffado->channels; i++) { |
---|
126 | | uint32_t *alsa_data_ptr = (uint32_t *)((char *)areas[i].addr + (areas[i].step * offset / 8)); |
---|
127 | | uint32_t *ffado_data_ptr = audiobuffers_raw + i*ffado->period; |
---|
128 | | memcpy(ffado_data_ptr, alsa_data_ptr, ffado->period * 4); |
---|
| 230 | debugOutput(DEBUG_LEVEL_VERBOSE, "PBK: wait\n"); |
---|
| 231 | res = ffado->buffer->waitForWrite(); |
---|
| 232 | debugOutput(DEBUG_LEVEL_VERBOSE, "PBK: done, fill: %d\n", ffado->buffer->getBufferFill()); |
---|
| 233 | |
---|
| 234 | if(res == IpcRingBuffer::eR_OK) { |
---|
| 235 | do { |
---|
| 236 | uint32_t *audiobuffers_raw; |
---|
| 237 | res = ffado->buffer->requestBlockForWrite((void**) &audiobuffers_raw); // pointer voodoo |
---|
| 238 | if(res == IpcRingBuffer::eR_OK) { |
---|
| 239 | // we have the memory block, do the actual transfer |
---|
| 240 | // silence the block |
---|
| 241 | memset(audiobuffers_raw, 0, ffado->channels * ffado->period * 4); |
---|
| 242 | if(io->state == SND_PCM_STATE_RUNNING) { |
---|
| 243 | // get the data address the data comes from |
---|
| 244 | areas = snd_pcm_ioplug_mmap_areas(io); |
---|
| 245 | |
---|
| 246 | // create the list of areas where the data goes to |
---|
| 247 | unsigned int channel = 0; |
---|
| 248 | for (channel = 0; channel < ffado->channels; channel++) { |
---|
| 249 | uint32_t *target = (audiobuffers_raw + channel*ffado->period); |
---|
| 250 | ffado->areas[channel].addr = target; |
---|
| 251 | ffado->areas[channel].first = 0; |
---|
| 252 | ffado->areas[channel].step = 4*8; // FIXME: hardcoded sample size |
---|
| 253 | } |
---|
| 254 | snd_pcm_uframes_t xfer = 0; |
---|
| 255 | while (xfer < ffado->period) { |
---|
| 256 | snd_pcm_uframes_t frames = ffado->period - xfer; |
---|
| 257 | snd_pcm_uframes_t offset = ffado->hw_ptr; |
---|
| 258 | snd_pcm_uframes_t cont = io->buffer_size - offset; |
---|
| 259 | |
---|
| 260 | if (cont < frames) |
---|
| 261 | frames = cont; |
---|
| 262 | |
---|
| 263 | for (channel = 0; channel < ffado->channels; channel++) { |
---|
| 264 | snd_pcm_area_copy(&ffado->areas[channel], xfer, &areas[channel], offset, frames, io->format); |
---|
| 265 | } |
---|
| 266 | |
---|
| 267 | ffado->hw_ptr += frames; |
---|
| 268 | ffado->hw_ptr %= io->buffer_size; |
---|
| 269 | xfer += frames; |
---|
| 270 | } |
---|
| 271 | } |
---|
| 272 | // release the block |
---|
| 273 | res = ffado->buffer->releaseBlockForWrite(); |
---|
| 274 | if(res != IpcRingBuffer::eR_OK) { |
---|
| 275 | debugOutput(DEBUG_LEVEL_NORMAL, "PBK: error committing memory block\n"); |
---|
| 276 | break; |
---|
| 277 | } |
---|
| 278 | } else if(res != IpcRingBuffer::eR_Again) { |
---|
| 279 | debugOutput(DEBUG_LEVEL_NORMAL, "PBK: error getting memory block\n"); |
---|
141 | | do { |
---|
142 | | uint32_t *audiobuffers_raw; |
---|
143 | | res = ffado->buffer->requestBlockForRead((void**) &audiobuffers_raw); // pointer voodoo |
---|
144 | | if(res == IpcRingBuffer::eR_OK) { |
---|
145 | | for (i = 0; i < ffado->channels; i++) { |
---|
146 | | uint32_t *alsa_data_ptr = (uint32_t *)((char *)areas[i].addr + (areas[i].step * offset / 8)); |
---|
147 | | uint32_t *ffado_data_ptr = audiobuffers_raw + i*ffado->period; |
---|
148 | | memcpy(alsa_data_ptr, ffado_data_ptr, ffado->period * 4); |
---|
| 289 | res = ffado->buffer->waitForRead(); |
---|
| 290 | if(res == IpcRingBuffer::eR_OK) { |
---|
| 291 | do { |
---|
| 292 | uint32_t *audiobuffers_raw; |
---|
| 293 | res = ffado->buffer->requestBlockForRead((void**) &audiobuffers_raw); // pointer voodoo |
---|
| 294 | if(res == IpcRingBuffer::eR_OK) { |
---|
| 295 | // we have the memory block, do the actual transfer |
---|
| 296 | if(io->state == SND_PCM_STATE_RUNNING) { |
---|
| 297 | // get the data address the data goes to |
---|
| 298 | areas = snd_pcm_ioplug_mmap_areas(io); |
---|
| 299 | |
---|
| 300 | // create the list of areas where the data comes from |
---|
| 301 | unsigned int channel = 0; |
---|
| 302 | for (channel = 0; channel < io->channels; channel++) { |
---|
| 303 | ffado->areas[channel].addr = audiobuffers_raw + channel*ffado->period; |
---|
| 304 | ffado->areas[channel].first = 0; |
---|
| 305 | ffado->areas[channel].step = 4*8; // FIXME: hardcoded sample size |
---|
| 306 | } |
---|
| 307 | snd_pcm_uframes_t xfer = 0; |
---|
| 308 | while (xfer < ffado->period) { |
---|
| 309 | snd_pcm_uframes_t frames = ffado->period - xfer; |
---|
| 310 | snd_pcm_uframes_t offset = ffado->hw_ptr; |
---|
| 311 | snd_pcm_uframes_t cont = io->buffer_size - offset; |
---|
| 312 | |
---|
| 313 | if (cont < frames) |
---|
| 314 | frames = cont; |
---|
| 315 | |
---|
| 316 | for (channel = 0; channel < io->channels; channel++) { |
---|
| 317 | snd_pcm_area_copy(&areas[channel], offset, &ffado->areas[channel], xfer, frames, io->format); |
---|
| 318 | } |
---|
| 319 | |
---|
| 320 | ffado->hw_ptr += frames; |
---|
| 321 | ffado->hw_ptr %= io->buffer_size; |
---|
| 322 | xfer += frames; |
---|
| 323 | } |
---|
| 324 | } |
---|
| 325 | // release the block |
---|
| 326 | res = ffado->buffer->releaseBlockForRead(); |
---|
| 327 | if(res != IpcRingBuffer::eR_OK) { |
---|
| 328 | debugOutput(DEBUG_LEVEL_NORMAL, "CAP: error committing memory block\n"); |
---|
| 329 | break; |
---|
| 330 | } |
---|
| 331 | } else if(res != IpcRingBuffer::eR_Again) { |
---|
| 332 | debugOutput(DEBUG_LEVEL_NORMAL, "CAP: error getting memory block\n"); |
---|