[Top][All Lists]
[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:28:03 2000 |
<grrr> cutted again.
To: address@hidden
Subject: Re: [Octal-dev] audio in linux
Bcc: address@hidden
--text follows this line--
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