int PeekSyncFromBuffer (audioBuffer_t *buffer, int channel, uint8_t *data_out, int data_size) { if(buffer != NULL) { jack_ringbuffer_peek(buffer->sync_buffers[channel], (char*) data_out, data_size); return data_size; } return -1; }
int ringbuffer_cread(jack_ringbuffer_t *rbuf, void *buf, size_t bufsz, int advance, uint32_t *tag, size_t *len) /* C version: returns 1 on success and 0 on error */ { jack_ringbuffer_data_t vec[2]; hdr_t hdr; uint32_t len0; size_t cnt; /* peek for header */ cnt = jack_ringbuffer_peek(rbuf, (char*)&hdr, sizeof(hdr)); if(cnt != sizeof(hdr)) return 0; /* see if there are 'len' bytes of data available */ cnt = jack_ringbuffer_read_space(rbuf); if( cnt < (sizeof(hdr) + hdr.len) ) return 0; /* check if data fits in the user provided buffer */ if(hdr.len > bufsz ) return luajack_error("not enough space for ringbuffer_read() " "(at least %u bytes needed)", hdr.len); *tag = hdr.tag; *len = hdr.len; if(hdr.len == 0) /* tag only */ { if(advance) jack_ringbuffer_read_advance(rbuf, sizeof(hdr)); if(bufsz>0) ((char*)buf)[0]='\0'; return 1; } /* get the read vector */ jack_ringbuffer_get_read_vector(rbuf, vec); /* copy the data part in the user provided buffer */ if(vec[0].len >= (sizeof(hdr) + hdr.len)) /* all the data are in vec[0] */ memcpy(buf, vec[0].buf + sizeof(hdr), hdr.len); else if(vec[0].len > sizeof(hdr)) /* part of the data are in vec[0] */ { len0 = vec[0].len - sizeof(hdr); memcpy(buf, vec[0].buf + sizeof(hdr), len0); memcpy((char*)buf + len0, vec[1].buf, hdr.len - len0); } else /* part of the header and all of the data are in vec[1] */ { len0 = sizeof(hdr) - vec[0].len; /* bytes oh header in vec[1] */ memcpy((char*)buf, vec[1].buf + len0, hdr.len); } if(advance) jack_ringbuffer_read_advance(rbuf, sizeof(hdr) + hdr.len); return 1; }
int ringbuffer_luaread(jack_ringbuffer_t *rbuf, lua_State *L, int advance) /* tag, data = read() * returns tag=nil if there is not a complete message (header+data) in * the ringbuffer * if the header.len is 0, data is returned as an empty string ("") */ { jack_ringbuffer_data_t vec[2]; hdr_t hdr; uint32_t len; size_t cnt; /* peek for header */ cnt = jack_ringbuffer_peek(rbuf, (char*)&hdr, sizeof(hdr)); if(cnt != sizeof(hdr)) { lua_pushnil(L); return 1; } /* see if there are 'len' bytes of data available */ cnt = jack_ringbuffer_read_space(rbuf); if( cnt < (sizeof(hdr) + hdr.len) ) { lua_pushnil(L); return 1; } lua_pushinteger(L, hdr.tag); if(hdr.len == 0) /* header only */ { if(advance) jack_ringbuffer_read_advance(rbuf, sizeof(hdr)); lua_pushstring(L, ""); return 2; } /* get the read vector */ jack_ringbuffer_get_read_vector(rbuf, vec); //printf("vec[0].len=%u, vec[1].len=%u hdr.len=%u\n",vec[0].len,vec[1].len,hdr.len); if(vec[0].len >= (sizeof(hdr) + hdr.len)) /* data fits in vec[0] */ lua_pushlstring(L, vec[0].buf + sizeof(hdr), hdr.len); else if(vec[0].len > sizeof(hdr)) { len = vec[0].len - sizeof(hdr); lua_pushlstring(L, vec[0].buf + sizeof(hdr), len); lua_pushlstring(L, vec[1].buf, hdr.len - len); lua_concat(L, 2); } else /* vec[0] contains only the header or part of it (data is all in vec[1]) */ { len = sizeof(hdr) - vec[0].len; /* the first len bytes in vec1 are part of the header */ lua_pushlstring(L, vec[1].buf + len, hdr.len); } if(advance) jack_ringbuffer_read_advance(rbuf, sizeof(hdr) + hdr.len); return 2; }
// MIDI events capture method. void qmidinetJackMidiDevice::capture (void) { if (m_pJackBufferIn == NULL) return; char *pchBuffer; qmidinetJackMidiEvent ev; while (jack_ringbuffer_peek(m_pJackBufferIn, (char *) &ev, sizeof(ev)) == sizeof(ev)) { jack_ringbuffer_read_advance(m_pJackBufferIn, sizeof(ev)); pchBuffer = m_pQueueIn->push(ev.port, ev.event.time, ev.event.size); if (pchBuffer) jack_ringbuffer_read(m_pJackBufferIn, pchBuffer, ev.event.size); else jack_ringbuffer_read_advance(m_pJackBufferIn, ev.event.size); } float sample_rate = jack_get_sample_rate(m_pJackClient); jack_nframes_t frame_time = jack_frame_time(m_pJackClient); while ((pchBuffer = m_pQueueIn->pop( &ev.port, &ev.event.time, &ev.event.size)) != NULL) { ev.event.time += m_last_frame_time; if (ev.event.time > frame_time) { unsigned long sleep_time = ev.event.time - frame_time; float secs = float(sleep_time) / sample_rate; if (secs > 0.0001f) { #if 0 // defined(__GNUC__) && defined(Q_OS_LINUX) struct timespec ts; ts.tv_sec = time_t(secs); ts.tv_nsec = long(1E+9f * (secs - ts.tv_sec)); ::nanosleep(&ts, NULL); #else m_pRecvThread->usleep(long(1E+6f * secs)); #endif } frame_time = ev.event.time; } #ifdef CONFIG_DEBUG // - show (input) event for debug purposes... fprintf(stderr, "JACK MIDI In Port %d: (%d)", ev.port, int(ev.event.size)); for (unsigned int i = 0; i < ev.event.size; ++i) fprintf(stderr, " 0x%02x", (unsigned char) pchBuffer[i]); fprintf(stderr, "\n"); #endif recvData((unsigned char *) pchBuffer, ev.event.size, ev.port); } }
int ringbuffer_cread_advance(jack_ringbuffer_t *rbuf) /* C version: returns 1 or 0 */ { hdr_t hdr; /* peek for header */ size_t cnt = jack_ringbuffer_peek(rbuf, (char*)&hdr, sizeof(hdr)); if(cnt == sizeof(hdr)) { /* see if there are 'len' bytes of data available */ cnt = jack_ringbuffer_read_space(rbuf); if( cnt >= (sizeof(hdr) + hdr.len) ) { jack_ringbuffer_read_advance(rbuf, sizeof(hdr) + hdr.len); return 1; } } return 0; }
int ringbuffer_luaread_advance(jack_ringbuffer_t *rbuf, lua_State *L) /* call this after a peek to just advance the read pointer */ { hdr_t hdr; /* peek for header */ size_t cnt = jack_ringbuffer_peek(rbuf, (char*)&hdr, sizeof(hdr)); if(cnt == sizeof(hdr)) { cnt = jack_ringbuffer_read_space(rbuf); if( cnt >= (sizeof(hdr) + hdr.len)) { jack_ringbuffer_read_advance(rbuf, sizeof(hdr) + hdr.len); lua_pushboolean(L, 1); return 1; } } lua_pushboolean(L, 0); return 1; }
static int a2j_process (jack_nframes_t nframes, void * arg) { struct a2j* self = (struct a2j *) arg; struct a2j_stream * stream_ptr; int i; struct a2j_port ** port_ptr; struct a2j_port * port; if (g_freewheeling) { return 0; } self->cycle_start = jack_last_frame_time (self->jack_client); stream_ptr = &self->stream; a2j_add_ports (stream_ptr); // process ports for (i = 0 ; i < PORT_HASH_SIZE ; i++) { port_ptr = &stream_ptr->port_hash[i]; while (*port_ptr != NULL) { struct a2j_alsa_midi_event ev; jack_nframes_t now; jack_nframes_t one_period; char *ev_buf; port = *port_ptr; if (port->is_dead) { if (jack_ringbuffer_write_space (self->port_del) >= sizeof(port_ptr)) { a2j_debug("jack: removed port %s", port->name); *port_ptr = port->next; jack_ringbuffer_write (self->port_del, (char*)&port, sizeof(port)); } else { a2j_error ("port deletion lost - no space in event buffer!"); } port_ptr = &port->next; continue; } port->jack_buf = jack_port_get_buffer(port->jack_port, nframes); /* grab data queued by the ALSA input thread and write it into the JACK port buffer. it will delivered during the JACK period that this function is called from. */ /* first clear the JACK port buffer in preparation for new data */ // a2j_debug ("PORT: %s process input", jack_port_name (port->jack_port)); jack_midi_clear_buffer (port->jack_buf); now = jack_frame_time (self->jack_client); one_period = jack_get_buffer_size (self->jack_client); while (jack_ringbuffer_peek (port->inbound_events, (char*)&ev, sizeof(ev) ) == sizeof(ev) ) { jack_midi_data_t* buf; jack_nframes_t offset; if (ev.time >= self->cycle_start) { break; } //jack_ringbuffer_read_advance (port->inbound_events, sizeof (ev)); ev_buf = (char *) alloca( sizeof(ev) + ev.size ); if (jack_ringbuffer_peek (port->inbound_events, ev_buf, sizeof(ev) + ev.size ) != sizeof(ev) + ev.size) break; offset = self->cycle_start - ev.time; if (offset > one_period) { /* from a previous cycle, somehow. cram it in at the front */ offset = 0; } else { /* offset from start of the current cycle */ offset = one_period - offset; } a2j_debug ("event at %d offset %d", ev.time, offset); /* make sure there is space for it */ buf = jack_midi_event_reserve (port->jack_buf, offset, ev.size); if (buf) { /* grab the event */ memcpy( buf, ev_buf + sizeof(ev), ev.size ); } else { /* throw it away (no space) */ a2j_error ("threw away MIDI event - not reserved at time %d", ev.time); } jack_ringbuffer_read_advance (port->inbound_events, sizeof(ev) + ev.size); a2j_debug("input on %s: sucked %d bytes from inbound at %d", jack_port_name (port->jack_port), ev.size, ev.time); } port_ptr = &port->next; } } return 0; }
size_t JackRingbuffer::peek(char* dest, size_t cnt) { return jack_ringbuffer_peek(ringbuffer_, dest, cnt); }
size_t ringbuffer_peek(jack_ringbuffer_t *rb, float *dest, size_t cnt) { return jack_ringbuffer_peek(rb, (char*)dest, cnt * sizeof(float))/sizeof(float); }
// JACK specifics. int qmidinetJackMidiDevice::process ( jack_nframes_t nframes ) { jack_nframes_t buffer_size = jack_get_buffer_size(m_pJackClient); m_last_frame_time = jack_last_frame_time(m_pJackClient); // Enqueue/dequeue events // to/from ring-buffers... for (int i = 0; i < m_nports; ++i) { if (m_ppJackPortIn && m_ppJackPortIn[i] && m_pJackBufferIn) { void *pvBufferIn = jack_port_get_buffer(m_ppJackPortIn[i], nframes); const int nevents = jack_midi_get_event_count(pvBufferIn); const unsigned int nlimit = jack_ringbuffer_write_space(m_pJackBufferIn); unsigned char achBuffer[nlimit]; unsigned char *pchBuffer = &achBuffer[0]; unsigned int nwrite = 0; for (int n = 0; n < nevents; ++n) { if (nwrite + sizeof(qmidinetJackMidiEvent) >= nlimit) break; qmidinetJackMidiEvent *pJackEventIn = (struct qmidinetJackMidiEvent *) pchBuffer; jack_midi_event_get(&pJackEventIn->event, pvBufferIn, n); if (nwrite + sizeof(qmidinetJackMidiEvent) + pJackEventIn->event.size >= nlimit) break; pJackEventIn->port = i; pchBuffer += sizeof(qmidinetJackMidiEvent); nwrite += sizeof(qmidinetJackMidiEvent); ::memcpy(pchBuffer, pJackEventIn->event.buffer, pJackEventIn->event.size); pchBuffer += pJackEventIn->event.size; nwrite += pJackEventIn->event.size; } if (nwrite > 0) { jack_ringbuffer_write(m_pJackBufferIn, (const char *) achBuffer, nwrite); } } if (m_ppJackPortOut && m_ppJackPortOut[i] && m_pJackBufferOut) { void *pvBufferOut = jack_port_get_buffer(m_ppJackPortOut[i], nframes); jack_midi_clear_buffer(pvBufferOut); const unsigned int nlimit = jack_midi_max_event_size(pvBufferOut); unsigned int nread = 0; qmidinetJackMidiEvent ev; while (jack_ringbuffer_peek(m_pJackBufferOut, (char *) &ev, sizeof(ev)) == sizeof(ev) && nread < nlimit) { if (ev.port != i) break; if (ev.event.time > m_last_frame_time) break; jack_nframes_t offset = m_last_frame_time - ev.event.time; if (offset > buffer_size) offset = 0; else offset = buffer_size - offset; jack_ringbuffer_read_advance(m_pJackBufferOut, sizeof(ev)); jack_midi_data_t *pMidiData = jack_midi_event_reserve(pvBufferOut, offset, ev.event.size); if (pMidiData) jack_ringbuffer_read(m_pJackBufferOut, (char *) pMidiData, ev.event.size); else jack_ringbuffer_read_advance(m_pJackBufferOut, ev.event.size); nread += ev.event.size; } } } if (m_pJackBufferIn && jack_ringbuffer_read_space(m_pJackBufferIn) > 0) m_pRecvThread->sync(); return 0; }
int32 ad_read(ad_rec_t * handle, int16 * buf, int32 max) { #ifdef HAVE_SAMPLERATE_H int resample_error; #endif if (!handle->recording) return AD_EOF; size_t length = sample_size * max; #ifdef HAVE_SAMPLERATE_H // Resample the data from the sample rate set in the jack server to that required // by sphinx length = jack_ringbuffer_peek (handle->rbuffer, (char*) handle->sample_buffer, length); size_t length_in_samples = length / sample_size; if(handle->resample_state == NULL) return AD_EOF; // We will try to downsample if jackd is running at a higher sample rate jack_nframes_t jack_samplerate = jack_get_sample_rate(handle->client); SRC_DATA data; data.data_in = handle->sample_buffer; data.input_frames = length_in_samples; data.data_out = handle->resample_buffer; data.output_frames = BUFFER_SIZE / sample_size; data.src_ratio = (float) handle->sps / jack_samplerate; data.end_of_input = 0; if ((resample_error = src_process(handle->resample_state, &data)) != 0) { fprintf (stderr, "resample error %s\n", src_strerror (resample_error)); return 1; } for(int i=0; i<data.output_frames_gen; i++) { buf[i] = (int16) (int16_range_over_two * (handle->resample_buffer[i] + 1.0) + SHRT_MIN); } jack_ringbuffer_read_advance(handle->rbuffer, data.input_frames_used * sample_size); if(length == 0 && (!handle->recording)) { return AD_EOF; } return data.output_frames_gen; #else length = jack_ringbuffer_read (handle->rbuffer, (char*) handle->sample_buffer, length); size_t length_in_samples = length / sample_size; for(int i=0; i<length_in_samples; i++) { buf[i] = (int16) (int16_range_over_two * (handle->sample_buffer[i] + 1.0) + SHRT_MIN); } if(length == 0 && (!handle->recording)) { return AD_EOF; } return length_in_samples; #endif }