Example #1
0
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;
	}
Example #2
0
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);
	}
}
Example #4
0
			/**
			  @brief Read into an array

			  Read from the buffer into an array.

			  \param dest an array to be read into
			  \param cnt the number of elements to read into this array
			  */
			void read(Type *dest, unsigned cnt){
				jack_ringbuffer_data_t readVec[2];
				unsigned int read_size = sizeof(Type) * cnt;
				if(getReadSpace() <= 0){
					//throw error!!!!
					return;
				}

				//get the readvector
				jack_ringbuffer_get_read_vector(mRingBufferPtr, readVec);

				//if the first vector has enough data then just read from there
				if(readVec[0].len >= read_size){
					memcpy(dest, readVec[0].buf, read_size);
				} else {
					//if the first vector is zero length then read from the second
					if(readVec[0].len == 0){
						memcpy(dest, readVec[1].buf, read_size);
					} else {
						//this gets tricky
						char * byterep = (char *)dest;
						//first read the data out of the first vector
						memcpy(byterep, readVec[0].buf, readVec[0].len);
						//then read the rest out of the second
						memcpy(byterep + readVec[0].len, readVec[1].buf, read_size - readVec[0].len);
					}
				}
				//advance the read pointer
				jack_ringbuffer_read_advance(mRingBufferPtr, read_size);
			}
Example #5
0
/** flush buffers and reset. Must only be called from the RT thread. */
void
Disk_Stream::base_flush ( bool is_output )
{
    THREAD_ASSERT( RT );

    /* flush buffers */
    for ( int i = _rb.size(); i--; )
        jack_ringbuffer_read_advance( _rb[ i ], jack_ringbuffer_read_space( _rb[ i ] ) );

/*  sem_destroy( &_blocks ); */

/*     if ( is_output ) */
/*         sem_init( &_blocks, 0, _total_blocks ); */
/*     else */
/*         sem_init( &_blocks, 0, 0 ); */

    if ( is_output )
    {
        int n;
        sem_getvalue( &_blocks, &n );

        n = _total_blocks - n;

        while ( n-- )
            sem_post( &_blocks );
    }
    else
    {
        sem_destroy( &_blocks );

        sem_init( &_blocks, 0, 0 );
    }


}
Example #6
0
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;
	}
Example #7
0
/*
 * ============================ Input ==============================
 */
static
void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info *info)
{
	// process port->early_events
	alsa_midi_event_t ev;
	while (jack_ringbuffer_read(port->early_events, (char*)&ev, sizeof(ev))) {
		jack_midi_data_t* buf;
		int64_t time = ev.time - info->period_start;
		if (time < 0)
			time = 0;
		else if (time >= info->nframes)
			time = info->nframes - 1;
		buf = jack_midi_event_reserve(port->jack_buf, (jack_nframes_t)time, ev.size);
		if (buf)
			jack_ringbuffer_read(port->early_events, (char*)buf, ev.size);
		else
			jack_ringbuffer_read_advance(port->early_events, ev.size);
		debug_log("input: it's time for %d bytes at %lld", ev.size, time);
	}
}
Example #8
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;
	}
Example #9
0
static
void do_jack_input(process_jack_t *p)
{
    input_port_t *port = (input_port_t*) p->port;
    event_head_t event;
    while (jack_ringbuffer_read_space(port->base.event_ring) >= sizeof(event)) {
        jack_ringbuffer_data_t vec[2];
        jack_nframes_t time;
        int i, todo;

        jack_ringbuffer_read(port->base.event_ring, (char*)&event, sizeof(event));
        // TODO: take into account possible warping
        if ((event.time + p->nframes) < p->frame_time)
            time = 0;
        else if (event.time >= p->frame_time)
            time = p->nframes -1;
        else
            time = event.time + p->nframes - p->frame_time;

        jack_ringbuffer_get_read_vector(port->base.data_ring, vec);
        assert ((vec[0].len + vec[1].len) >= event.size);

        if (event.overruns)
            midi_unpack_reset(&port->unpack);

        todo = event.size;
        for (i=0; i<2 && todo>0; ++i) {
            int avail = todo < vec[i].len ? todo : vec[i].len;
            int done = midi_unpack_buf(&port->unpack, (unsigned char*)vec[i].buf, avail, p->buffer, time);
            if (done != avail) {
                debug_log("jack_in: buffer overflow in port %s", port->base.name);
                break;
            }
            todo -= done;
        }
        jack_ringbuffer_read_advance(port->base.data_ring, event.size);
    }
}
Example #10
0
int JackWinMMEDriver::Read()
{
    size_t size;

    for (int chan = 0; chan < fCaptureChannels; chan++)  {

        if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) {

            JackMidiBuffer* midi_buffer = GetInputBuffer(chan);

            if (jack_ringbuffer_read_space (fRingBuffer[chan]) == 0) {
                // Reset buffer
                midi_buffer->Reset(midi_buffer->nframes);
            } else {

                while ((size = jack_ringbuffer_read_space (fRingBuffer[chan])) > 0) {

                    //jack_info("jack_ringbuffer_read_space %d", size);
                    int ev_count = 0;
                    jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int));

                    if (ev_count > 0) {
                        for (int j = 0; j < ev_count; j++)  {
                            unsigned int event_len = 3;
                            // Read event actual data
                            jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len);
                            jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len);
                        }
                    }
                }
            }
        } else {
            //jack_info("Consume ring buffer");
            jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan]));
        }
    }
    return 0;
}
void
JackRingbuffer::advanceRead(size_t cnt)
{
	jack_ringbuffer_read_advance(ringbuffer_, cnt);
}
Example #12
0
static
int do_midi_output(process_midi_t *proc)
{
    int worked = 0;
    output_port_t *port = (output_port_t*) proc->port;

    if (!midi_is_ready(proc))
        return 0;

    // eat events
    while (port->next_event.time <= proc->cur_time) {
        port->todo += port->next_event.size;
        if (jack_ringbuffer_read(port->base.event_ring, (char*)&port->next_event, sizeof(port->next_event))!=sizeof(port->next_event)) {
            port->next_event.time = 0;
            port->next_event.size = 0;
            break;
        } else
            debug_log("midi_out: at %ld got %d bytes for %ld", (long)proc->cur_time, (int)port->next_event.size, (long)port->next_event.time);
    }

    if (port->todo)
        debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time);

    // calc next wakeup time
    if (!port->todo && port->next_event.time && port->next_event.time < proc->next_time) {
        proc->next_time = port->next_event.time;
        debug_log("midi_out: next_time = %ld", (long)proc->next_time);
    }

    if (port->todo && port->base.is_ready) {
        // write data
        int size = port->todo;
        int res;
        jack_ringbuffer_data_t vec[2];

        jack_ringbuffer_get_read_vector(port->base.data_ring, vec);
        if (size > vec[0].len) {
            size = vec[0].len;
            assert (size > 0);
        }
        res = snd_rawmidi_write(port->base.rawmidi, vec[0].buf, size);
        if (res > 0) {
            jack_ringbuffer_read_advance(port->base.data_ring, res);
            debug_log("midi_out: written %d bytes to %s", res, port->base.name);
            port->todo -= res;
            worked = 1;
        } else if (res == -EWOULDBLOCK) {
            port->base.is_ready = 0;
            debug_log("midi_out: -EWOULDBLOCK on %s", port->base.name);
            return 1;
        } else {
            error_log("midi_out: writing to port %s failed: %s", port->base.name, snd_strerror(res));
            return 0;
        }
        snd_rawmidi_drain(port->base.rawmidi);
    }

    // update pfds for this port
    if (!midi_update_pfds(proc))
        return 0;

    if (!port->todo) {
        int i;
        if (worked)
            debug_log("midi_out: relaxing on %s", port->base.name);
        for (i=0; i<port->base.npfds; ++i)
            proc->wpfds[i].events &= ~POLLOUT;
    } else {
        int i;
        for (i=0; i<port->base.npfds; ++i)
            proc->wpfds[i].events |= POLLOUT;
    }
    return 1;
}
Example #13
0
int process(jack_nframes_t nframes, void *arg) {
    struct guitarseq *guitarseq = arg;
    if(!guitarseq) {
        fprintf(stderr, "No guitarseq instance!\n");
        return 1;
    }

    void* port_buf;
    jack_nframes_t now = jack_frame_time (guitarseq->jack_client);

    //Output
    port_buf = jack_port_get_buffer(guitarseq->out_port, nframes);
    jack_midi_clear_buffer(port_buf);
    while (1) {
        jack_nframes_t time;
        //TODO: Do a safer read, in case only part of the message is here
        if (!jack_ringbuffer_read (guitarseq->out_buffer, (char *)&time, sizeof(time))) {
            break;
        }

        // from the future?
        if (time >= now) {
            break;
        }

        // time it right
        jack_nframes_t offset = time - now + nframes - 1;

        // get the size of the event
        size_t size;
        jack_ringbuffer_read(guitarseq->out_buffer, (char *)&size, sizeof(size));

        INFO("out event at %u%+d size %zu\n", now, offset, size);

        if (offset > nframes)
            // from the past, somehow. cram it in at the front
            offset = 0;

        // proceed to giving it to jack
        jack_midi_data_t *buffer = jack_midi_event_reserve (port_buf, offset, size);
        if(buffer) {
            jack_ringbuffer_read(guitarseq->out_buffer, (char *)buffer, size);
        } else {
            // throw it away :( TODO: find more
            jack_ringbuffer_read_advance (guitarseq->out_buffer, size);
            ERROR("threw away MIDI event - no space reserved at time %u offset %d\n",time,offset);
        }
    }

    // 	Input
    port_buf = jack_port_get_buffer(guitarseq->in_port, nframes);
    jack_nframes_t event_count = jack_midi_get_event_count(port_buf);
    for(jack_nframes_t i=0; i<event_count; i++) {
        jack_midi_event_t in_event;
        jack_midi_event_get(&in_event, port_buf, i);

        //adds a note to the ringbuffer
        if (jack_ringbuffer_write_space(guitarseq->in_buffer) >= sizeof(in_event.time)+sizeof(in_event.size)+in_event.size) {
            jack_ringbuffer_write(guitarseq->in_buffer, (char *)&in_event.time, sizeof(in_event.time));
            jack_ringbuffer_write(guitarseq->in_buffer, (char *)&in_event.size, sizeof(in_event.size));
            jack_ringbuffer_write(guitarseq->in_buffer, (char *)in_event.buffer, in_event.size);
        } else {
            ERROR("Couldn't write to ringbuffer at %u, %zu midi data bytes lost\n", in_event.time, in_event.size);
        }
    }

    return 0;
}
Example #14
0
void
Record_DS::disk_thread ( void )
{
    _thread.name( "Capture" );

    DMESSAGE( "capture thread running..." );

    track()->record( _capture, _frame );

    const nframes_t nframes = _nframes * _disk_io_blocks;

    /* buffer to hold the interleaved data returned by the track reader */
    sample_t *buf = new sample_t[ nframes * channels() ];
#ifndef AVOID_UNNECESSARY_COPYING
    sample_t *cbuf = new sample_t[ nframes ];
#endif

    const size_t block_size = nframes * sizeof( sample_t );

    int blocks_ready = 0;

    while ( wait_for_block() )
    {
        if ( ++blocks_ready < _disk_io_blocks )
            continue;
        else
            blocks_ready = 0;

        /* pull data from the per-channel ringbuffers and interlace it */
        for ( int i = channels(); i--; )
        {

#ifdef AVOID_UNNECESSARY_COPYING

            /* interleave direcectly from the ringbuffer to avoid
             * unnecessary copying */

            jack_ringbuffer_data_t rbd[2];

            memset( rbd, 0, sizeof( rbd ) );

            jack_ringbuffer_get_read_vector( _rb[ i ], rbd );

            if ( rbd[ 0 ].len >= block_size )
            {
                /* it'll all fit in one go */
                buffer_interleave_one_channel( buf, (sample_t*)rbd[ 0 ].buf, i, channels(), nframes );
            }
            else if ( rbd[ 0 ].len + rbd[ 1 ].len >= block_size )
            {
                /* there's enough space in the ringbuffer, but it's not contiguous */

                assert( ! ( rbd[ 0 ].len % sizeof( sample_t )  ) );

                const nframes_t f = rbd[ 0 ].len / sizeof( sample_t );

                /* do the first half */
                buffer_deinterleave_one_channel( (sample_t*)rbd[ 0 ].buf, buf, i, channels(), f );
                buffer_interleave_one_channel( buf, (sample_t*)rbd[ 0 ].buf, i, channels(), f );

                assert( rbd[ 1 ].len >= ( nframes - f ) * sizeof( sample_t ) );

                /* do the second half */
                buffer_interleave_one_channel( buf + f, (sample_t*)rbd[ 0 ].buf, i, channels(), nframes - f );

            }
            else
                ++_xruns;

            jack_ringbuffer_read_advance( _rb[ i ], block_size );
#else
            if ( jack_ringbuffer_read( _rb[ i ], (char*)cbuf, block_size ) < block_size )
                ++_xruns;

            buffer_interleave_one_channel( buf, cbuf, i, channels(), nframes );
#endif

        }

        write_block( buf, nframes );

    }

    DMESSAGE( "capture thread terminating" );

    /* flush what remains in the buffer out to disk */

    {
        /* use JACk sized blocks for this last bit */
        const nframes_t nframes = _nframes;
        const size_t block_size = _nframes * sizeof( sample_t );

#ifdef AVOID_UNNECESSARY_COPYING
        sample_t *cbuf = new sample_t[ nframes ];
#endif

        while ( blocks_ready-- > 0 || ( ! sem_trywait( &_blocks ) && errno != EAGAIN ) )
        {

                for ( int i = channels(); i--; )
                {
                    jack_ringbuffer_read( _rb[ i ], (char*)cbuf, block_size );

                    buffer_interleave_one_channel( buf, cbuf, i, channels(), nframes );
                }

                const nframes_t frames_remaining = (_stop_frame - _frame ) - _frames_written;

                if ( frames_remaining < nframes )
                {
                    /* this is the last block, might be partial  */
                    write_block( buf, frames_remaining );
                    break;
                }
                else
                    write_block( buf, nframes );
        }

#ifdef AVOID_UNNECESSARY_COPYING
        delete[] cbuf;
#endif

    }

    delete[] buf;
#ifndef AVOID_UNNECESSARY_COPYING
    delete[] cbuf;
#endif

    DMESSAGE( "finalzing capture" );

    Track::Capture *c = _capture;

    _capture = NULL;

    /* now finalize the recording */

    track()->finalize( c, _stop_frame );

    delete c;

    _terminate = false;

    DMESSAGE( "capture thread gone" );

    _thread.exit();
}
Example #15
0
JackResampler::JackResampler()
    :fRatio(1),fRingBufferSize(DEFAULT_RB_SIZE)
{
    fRingBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * fRingBufferSize);
    jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize) / 2);
}
//================================================================
int process(jack_nframes_t nframes, void *arg)
{
	//fprintf(stderr,".");
	//return 0;

	//if shutting down fill buffers with 0 and return
	if(shutdown_in_progress==1)
	{
		int i;
		for(i=0; i < output_port_count; i++)
		{
			sample_t *o1;
			o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);
			//memset(o1, 0, bytes_per_sample*nframes);
			//always 4 bytes, 32 bit float
			memset(o1, 0, 4*nframes);
		}
		return 0;
	}

	if(process_enabled==1)
	{
		//if no data for this cycle(all channels) 
		//is available(!), fill buffers with 0 or re-use old buffers and return
		if(jack_ringbuffer_read_space(rb) < port_count * bytes_per_sample*nframes)
		{
			int i;
			for(i=0; i < output_port_count; i++)
			{
				if(shutdown_in_progress==1 || process_enabled!=1)
				{
					return 0;
				}

				if(zero_on_underflow==1)
				{
					sample_t *o1;
					o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);

					//memset(o1, 0, bytes_per_sample*nframes);
					//always 4 bytes, 32 bit float
					memset(o1, 0, 4*nframes);
				}
				print_info();
			}

			multi_channel_drop_counter++;

			if(rebuffer_on_underflow==1)
			{
				pre_buffer_counter=0;
				process_enabled=0;
			}

			//reset avg calculation
			time_interval_avg=0;
			msg_received_counter=0;
			fscs_avg_counter=0;

			return 0;
		}//end not enough data available in ringbuffer

		process_cycle_counter++;

		if(process_cycle_counter>receive_max-1 && test_mode==1)
		{
			last_test_cycle=1;
		}

		//init to 0. increment before use
		fscs_avg_counter++;

		frames_since_cycle_start_sum+=frames_since_cycle_start;
		frames_since_cycle_start_avg=frames_since_cycle_start_sum/fscs_avg_counter;

		//check and reset after use
		if(fscs_avg_calc_interval>=fscs_avg_counter)
		{
			fscs_avg_counter=0;
			frames_since_cycle_start_sum=0;	
		}

		//if sender sends more channels than we have output channels, ignore them
		int i;
		for(i=0; i<port_count; i++)
		{
			if(shutdown_in_progress==1 || process_enabled!=1)
			{
				return 0;
			}

			sample_t *o1;
			o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);

			int16_t *o1_16;

			if(bytes_per_sample==2)
			{
				o1_16=malloc(bytes_per_sample*nframes);
			}

			//32 bit float
			if(bytes_per_sample==4)
			{
				jack_ringbuffer_read(rb, (char*)o1, bytes_per_sample*nframes);
			}
			//16 bit pcm
			else
			{
				jack_ringbuffer_read(rb, (char*)o1_16, bytes_per_sample*nframes);

				int x;
				for(x=0;x<nframes;x++)
				{
					o1[x]=(float)MIN_(MAX_((float)o1_16[x]/32760,-1.0f),1.0f);
				}

				free(o1_16);
			}

			/*
			fprintf(stderr,"\rreceiving from %s:%s",
				sender_host,sender_port
			);
			*/

			print_info();

		}//end for i < port_count

		//requested via /buffer, for test purposes (make buffer "tight")
		if(requested_drop_count>0)
		{
			uint64_t drop_bytes_count=requested_drop_count
				*port_count*period_size*bytes_per_sample;

			jack_ringbuffer_read_advance(rb,drop_bytes_count);

			requested_drop_count=0;
			multi_channel_drop_counter=0;
		}
	}//end if process_enabled==1
	else //if process_enabled==0
	{
		int i;
		for(i=0; i<port_count; i++)
		{
			if(shutdown_in_progress==1 || process_enabled!=1)
			{
				return 0;
			}

			sample_t *o1;
			o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);

			//this is per channel, not per cycle. *port_count
			if(relaxed_display_counter>=update_display_every_nth_cycle*port_count
				|| last_test_cycle==1
			)
			{
				//only for init
				if((int)message_number<=0 && starting_transmission==0)
				{
					if(shutup==0 && quiet==0)
					{
						fprintf(stderr,"\rwaiting for audio input data...");
					}
					io_simple("/wait_for_input");
				}
				else
				{
					if(shutup==0 && quiet==0)
					{
						fprintf(stderr,"\r# %" PRId64 " buffering... mc periods to go: %" PRId64 "%s",
							message_number,
							pre_buffer_size-pre_buffer_counter,
							"\033[0J"
						);
					}

					if(io_())
					{
						lo_message msgio=lo_message_new();

						lo_message_add_int64(msgio,message_number);
						lo_message_add_int64(msgio,pre_buffer_size-pre_buffer_counter);

						lo_send_message(loio, "/buffering", msgio);
						lo_message_free(msgio);
					}
				}

				fflush(stderr);

				relaxed_display_counter=0;
			}
			relaxed_display_counter++;

			//set output buffer silent
			//memset(o1, 0, port_count*bytes_per_sample*nframes);
			//always 4 bytes, 32 bit float
			memset(o1, 0, port_count*4*nframes);
		}//end for i < port_count
	}//end process_enabled==0

	//tasks independent of process_enabled 0/1

	//if sender sends less channels than we have output channels, wee need to fill them with 0
	if(input_port_count < output_port_count)
	{
		int i;
		for(i=0;i < (output_port_count-input_port_count);i++)
		{
			//sample_t *o1;
			//o1=(sample_t*)
			/////?
			jack_port_get_buffer(ioPortArray[input_port_count+i], nframes);
		}
	}

	if(last_test_cycle==1)
	{
		if(shutup==0)
		{
			fprintf(stderr,"\ntest finished after %" PRId64 " process cycles\n",process_cycle_counter);
			fprintf(stderr,"(waiting and buffering cycles not included)\n");
		}

		io_simple_long("/test_finished",process_cycle_counter);

		shutdown_in_progress=1;
	}

	//simulate long cycle process duration
	//usleep(1000);

	frames_since_cycle_start=jack_frames_since_cycle_start(client);

	return 0;
} //end process()
Example #17
0
void ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt)
{
    jack_ringbuffer_read_advance(rb, cnt * sizeof(float));
}
Example #18
0
void *jack_player_thread(void *unused){
	WfAudioInfo* nfo = &myplayer->info;
	const int nframes = 1024;
	float *tmpbuf = (float*) calloc(nframes * nfo->channels, sizeof(float));
	float *bufptr = tmpbuf;
#ifdef ENABLE_RESAMPLING
	size_t maxbufsiz = nframes;
	int err = 0;
	SRC_STATE* src_state = src_new(SRC_QUALITY, nfo->channels, NULL);
	SRC_DATA src_data;
	int nframes_r = floorf((float) nframes*m_fResampleRatio); ///< # of frames after resampling
#ifdef VARISPEED
	maxbufsiz = (2+nframes_r) * 2;
#else
	maxbufsiz = (1+nframes_r);
#endif
	float *smpbuf = (float*) calloc(maxbufsiz * nfo->channels, sizeof(float));

	src_data.input_frames  = nframes;
	src_data.output_frames = nframes_r;
	src_data.end_of_input  = 0;
	src_data.src_ratio     = m_fResampleRatio;
	src_data.input_frames_used = 0;
	src_data.output_frames_gen = 0;
	src_data.data_in       = tmpbuf;
	src_data.data_out      = smpbuf;
#else
	int nframes_r = nframes; // no resampling
#endif

	int ladspaerr = 0;
#if (defined ENABLE_LADSPA)
	if (m_use_effect && play->enable_effect) {
		int i;
		for(i=0;i<nfo->channels;i++) {
			ladspaerr |= ladspah_init(myplugin[i], m_use_effect, m_effectno, 
					jack_get_sample_rate(j_client) /* m_samplerate */, maxbufsiz);
		}
		if (ladspaerr) {
			dbg(0, "error setting up LADSPA plugin - effect disabled.\n");
		}
	} else {
		ladspaerr = 1;
	}
	play->effect_enabled = ladspaerr ? false : true; // read-only for GUI
#endif

	size_t rbchunk = nframes_r * nfo->channels * sizeof(float);
	play_position = 0;
	int64_t decoder_position = 0;

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	pthread_mutex_lock(&player_thread_lock);

	/** ALL SYSTEMS GO **/
	player_active = 1;
	while(thread_run) {
		int rv = ad_read(myplayer, tmpbuf, nframes * nfo->channels);

		if (rv > 0) decoder_position += rv / nfo->channels;

#ifdef JACK_MIDI
		const float pp[3] = {play->effect_param[0], play->effect_param[1] + midi_note, play->effect_param[2] + midi_octave};
#else
		const float pp[3] = {play->effect_param[0], play->effect_param[1], play->effect_param[2]};
#endif
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
		const float varispeed = play->playback_speed;
#if 0
		/* note: libsamplerate slowly approaches a new sample-rate slowly
		 * src_set_ratio() allow for immediate updates at loss of quality */
		static float oldspd = -1;
		if (oldspd != varispeed) {
			if ((err = src_set_ratio(src_state, m_fResampleRatio * varispeed))) dbg(0, "SRC ERROR: %s", src_strerror(err)); // instant change.
			oldspd = varispeed;
		}
#endif
		nframes_r = floorf((float) nframes * m_fResampleRatio * varispeed); ///< # of frames after resampling
		src_data.input_frames  = nframes;
		src_data.output_frames = nframes_r;
		src_data.src_ratio     = m_fResampleRatio * varispeed;
		src_data.end_of_input  = 0;
#endif

		if (rv != nframes * nfo->channels) {
			dbg(1, "end of file.");
			if (rv > 0) {
#ifdef ENABLE_RESAMPLING
# ifdef VARISPEED
				if (1) 
# else
				if(m_fResampleRatio != 1.0)
# endif
				{
					src_data.input_frames = rv / nfo->channels;
#ifdef VARISPEED
					src_data.output_frames = floorf((float)(rv / nfo->channels) * m_fResampleRatio * varispeed);
#else
					src_data.output_frames = floorf((float)(rv / nfo->channels) * m_fResampleRatio);
#endif
					src_data.end_of_input = play->config.loop ? 0 : 1;
					src_process(src_state, &src_data);
					bufptr = smpbuf;
					rv = src_data.output_frames_gen * nfo->channels;
				}
#endif
				if (!ladspaerr) {
					ladspah_set_param(myplugin, nfo->channels, 0 /*cents */, pp[0]); /* -100 .. 100 */
					ladspah_set_param(myplugin, nfo->channels, 1 /*semitones */, pp[1]); /* -12 .. 12 */
					ladspah_set_param(myplugin, nfo->channels, 2 /*octave */, pp[2]);    /*  -3 ..  3 */
					ladspah_process_nch(myplugin, nfo->channels, bufptr, rv / nfo->channels);
				}
				jack_ringbuffer_write(rb, (char *) bufptr, rv *  sizeof(float));
			}
			if (play->config.loop) {
				ad_seek(myplayer, 0);
				decoder_position = 0;
#ifdef ENABLE_RESAMPLING
				//src_reset (src_state); // XXX causes click
# ifdef VARISPEED
				if (1) 
# else
				if(m_fResampleRatio != 1.0)
# endif
				{
					src_data.end_of_input  = 0;
					src_data.input_frames  = nframes;
					src_data.output_frames = nframes_r;
				}
#endif
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
				while(thread_run && jack_ringbuffer_write_space(rb) <= maxbufsiz*nfo->channels*sizeof(float))
#else
				while(thread_run && jack_ringbuffer_write_space(rb) <= rbchunk)
#endif
				{
					pthread_cond_wait(&buffer_ready, &player_thread_lock);
				}
				continue;
			}
			else
				break;
		} /* end EOF handling */

#ifdef ENABLE_RESAMPLING
#ifdef VARISPEED
		if(1) // m_fResampleRatio*varispeed != 1.0)
#else
		if(m_fResampleRatio != 1.0)
#endif
		{
			if ((err=src_process(src_state, &src_data))) {
				dbg(0, "SRC PROCESS ERROR: %s", src_strerror(err));
			}
			bufptr = smpbuf;
			rbchunk = src_data.output_frames_gen * nfo->channels * sizeof(float);
		}
#endif
		if (!ladspaerr) {
			ladspah_set_param(myplugin, nfo->channels, 0 /*cent */, pp[0]); /* -100 .. 100 */
			ladspah_set_param(myplugin, nfo->channels, 1 /*semitones */, pp[1]); /* -12 .. 12 */
			ladspah_set_param(myplugin, nfo->channels, 2 /*octave */, pp[2]);    /*  -3 ..  3 */
			ladspah_process_nch(myplugin, nfo->channels, bufptr, rbchunk/ nfo->channels / sizeof(float));
		}
		jack_ringbuffer_write(rb, (char *) bufptr, rbchunk);

#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
		while(thread_run && jack_ringbuffer_write_space(rb) <= maxbufsiz*nfo->channels*sizeof(float))
#else
		while(thread_run && jack_ringbuffer_write_space(rb) <= rbchunk) 
#endif
		{
#if 1 // flush_ringbuffer on seek
			if (playpause && seek_request != -1) break; 
#endif
			pthread_cond_wait(&buffer_ready, &player_thread_lock);
		}

		/* Handle SEEKs */
		while (seek_request>=0 && seek_request<=1) {
			double csr = seek_request;
			decoder_position = floor(m_frames * seek_request);
			ad_seek(myplayer, decoder_position);
			if (csr == seek_request) {
				seek_request = -1;
#if 1 // flush_ringbuffer !
				size_t rs=jack_ringbuffer_read_space(rb);
				jack_ringbuffer_read_advance(rb,rs);
#endif
				break;
			}
		}
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
		update_playposition (decoder_position, varispeed);
#else
		update_playposition (decoder_position, 1.0);
#endif
	}

	/** END OF PLAYBACK **/
#if (defined ENABLE_RESAMPLING) && (defined VARISPEED)
	const float varispeed = play->playback_speed;
#else
	const float varispeed = 1.0;
#endif
	pthread_mutex_unlock(&player_thread_lock);

	if (thread_run) {
		// wait for ringbuffer to empty.
		while (!silent && !playpause) {
			usleep(20);
			update_playposition (decoder_position, varispeed);
		}
		thread_run = 0;
		player_active = 0;
		play->effect_enabled = false;
		int i;
		for(i=0;i<nfo->channels;i++) {
			ladspah_deinit(myplugin[i]);
		}
		JACKclose(); 
	}
	free(tmpbuf);
#ifdef ENABLE_RESAMPLING
	src_delete(src_state);
	free(smpbuf);
#endif
	player_active = 0;
	if(play->status != PLAY_PLAY_PENDING){
		play->next();
	}
	return NULL;
}
Example #19
0
// 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;
}
Example #20
0
void JackResampler::Reset(unsigned int new_size)
{
    fRingBufferSize = new_size;
    jack_ringbuffer_reset_size(fRingBuffer, sizeof(jack_default_audio_sample_t) * fRingBufferSize);
    jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize / 2));
}
Example #21
0
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;
}
Example #22
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
}