octal-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Octal-dev] audio in linux


From: Guenter Seethaler
Subject: Re: [Octal-dev] audio in linux
Date: Thu Aug 3 18:14:03 2000

Sorry, something went wrong with my first mail. (it was cutted)
(I found a mistake anyway. )

Johan Rydberg wrote:

> In main.c, line 58:
>
>   e->block_size = 8820;
>
> I want to change this, to for example:
>
>   e->block_size = 2205;
>
> Why?  To reduce latency from 200ms to 50ms. But when I do this,
> everything sounds very different.
>
> Any ideas?

I rever to main.c Revision 1.11 from octal-alpha-0.3a wich seems to be
the version your working on.

The actual code in main.c is just for test propose. You cant't set the
buffer_size for the latenzy  because its the tick_size right now.

Normaly the output will run as a thread. 
Every <latency_time-a little bit>  calculate and play the buffer. This
let us get keystrokes and slider changes and so on.
But also we have to play the patterns right on time.

here is a pseudo code for this:

/* some globals  */
int tick=0;
int rest_samples = 0;         /* samples to be calculated to get to the next 
tick_boundary */
mono_sample_buf * out_buffer;
out_offset = 0;              /* offset from out_buffer-pointer */
int tick_size =  (sampling_rate/(BPM*TPB/60));
song_ticks = 16;
.
.

thread
{
    while (tick < song_ticks)
    {
        play(buffer);
        if (tick = song_ticks && (loop == 1)) tick=0;
        sleep(latency-time - 5ms);
    }
}

play(buffer)  
{
    out_offset = 0;
    update machines /* to be interactive in latency time */
    while (out_offset < out_buffer_size)  /* fill out_buffer untill we play it 
*/
    {
        if  ( rest_samples > 0 ) {   /* we are not on a tick_position */
            if out_offset+ rest_samples >= out_buffer_size { /* output buffer 
will be filled and played */      
                e->block_size = out_buf_size - out_offset;
                do_block(e, master);
                copy(e->mix to out_buffer at out_offset with e->block_size) ;
                rest_samples -= block_size;
                output(out_buffer);  /* play the buffer */
                out_offset = 0;
                if (rest_samples == 0) tick++;
                return;
            } else { /* just copy the remaining samples in the buffer and 
generate a tick */
                e->block_size = rest_samples;
                do_block(e, master);
                copy(e->mix to out_buffer at out_offset with e->block_size) ;
                out_offset += rest_samples;
                rest_samples = 0;
                tick++;
            }
        }
        /* here we are sure to be at tick position */
        update machines;  /* read values from the patterns  */
        if (tick_size >= out_buffer_size - out_offset) { /* tick  dont fit in 
out_buffer */
            rest_samples = tick_size - (out_buffer_size - out_offset); 
            e->block_size = out_buffer_size - out_offset;
            do_block(e, master);
            copy(e->mix to out_buffer at out_offset with e->block_size);
            play(out_buffer); 
            out_offset=0;
            if (e->block_size == 0) tick++;
            return;
        }else {    /* tick fits in out_buffer so we just copy it in the 
out_buffer */
            e->block_size = tick_size;
            do_block(e, master);
            copy(e->mix to out_buffer at out_offset with e->block_size);
            out_offset += e->block_size; 
            tick++;
        }
    }
}

This is the way i did it in delphi with directX. So the response time is the 
latency and we still have the ticks ( note/parameter changes in the patterns ) 
at the right time. 
Am i thinking too complex on this ? 

Guenter


reply via email to

[Prev in Thread] Current Thread [Next in Thread]