const unsigned int SamplesPerMillisecond = ((double)SampleRate / 1000.0);
-/// The number of audio samples in an audio frame. Audio frames must be a
-/// power of two (this is a common hardware requirement) and must be shorter
-/// than any codec/modem frame in the program.
-const unsigned int AudioFrameSamples = 512;
+/// The number of audio samples in an audio frame. Some systems will require
+/// this to be a power of two (this is a common hardware requirement).
+const unsigned int AudioFrameSamples = SampleRate / 20;
/// The audio frame duration in milliseconds. The audio interfaces will
/// use this as a period size.
if ((error = snd_pcm_sw_params(handle, sw_params)) < 0)
do_throw(error, name, stream, "ALSA set software parameters");
-#if 0
// Dump sound parameters, for debugging.
snd_output_t * output = 0;
snd_output_stdio_attach(&output, stderr, 0);
fprintf(stderr, "%s\n", name);
snd_pcm_dump_setup(handle, output);
-#endif
snd_pcm_sw_params_free(sw_params);
// If more than this number of frames are queued for audio output, the
// latency is too high. Flush the output and print an overlong-delay message.
- const unsigned int MaximumDelayFrames = 8;
+ const unsigned int MaximumDelayFrames = 4;
// At the start of playback, preload the audio output with this many
// frames of zero data. This delays the output enough to avoid later
1,
SampleRate,
AudioFrameSamples,
- AudioFrameSamples * 2);
+ AudioFrameSamples * 3);
if ( handle == 0 )
do_throw(-ENODEV);
// If we've not started, allow the first write to be large, but
// not so large that we'll active the overlong-delay code.
if ( !started )
- return AudioFrameSamples * MaximumDelayFrames - FillFrames - 1;
+ return AudioFrameSamples * min(1, (MaximumDelayFrames - FillFrames - 1));
else
return available;
}
/// Run the main loop of FreeDV in half-duplex mode.
///
void half_duplex();
+
+ /// Wake when there is room in the output device.
+ void wake_output(AudioDevice *);
};
Run::Run(Interfaces * interfaces)
else if ( result < 0 )
std::cerr << "Transmitter I/O error: " << strerror(errno) << std::endl;
}
- if ( out_fifo.get_available() > 0 ) {
- // There are samples queued for the transmitter. Wake when there is room
- // in its buffer.
- if ( output_fd_base < 0 ) {
- output_fd_base = poll_fd_count;
- add_poll_device(i->transmitter);
- }
- }
- else {
- // There are no samples queued for the transmitter. Don't wake upon its
- // buffer availability.
- if ( output_fd_base > 0 ) {
- poll_fd_count = output_fd_base;
- output_fd_base = -1;
- }
- }
+ wake_output(i->transmitter);
if ( final ) {
if ( in_fifo.get_available() == 0
else if ( result < 0 )
std::cerr << "Transmitter I/O error: " << strerror(errno) << std::endl;
}
- if ( out_fifo.get_available() > 0 ) {
- // There are samples queued for the transmitter. Wake when there is room
- // in its buffer.
- if ( output_fd_base < 0 ) {
- output_fd_base = poll_fd_count;
- add_poll_device(i->transmitter);
- }
- }
- else {
- // There are no samples queued for the transmitter. Don't wake upon its
- // buffer availability.
- if ( output_fd_base > 0 ) {
- poll_fd_count = output_fd_base;
- output_fd_base = -1;
- }
- }
+ wake_output(i->transmitter);
if ( final ) {
if ( in_fifo.get_available() == 0
else if ( result < 0 )
std::cerr << "Loudspeaker I/O error: " << strerror(errno) << std::endl;
}
-
- if ( out_fifo.get_available() > 0 ) {
- // std::cerr << out_fifo.get_available() / 2 << ' ';
- // There are samples queued for the loudspeaker. Wake when there is room
- // in its buffer.
- if ( output_fd_base < 0 ) {
- output_fd_base = poll_fd_count;
- add_poll_device(i->transmitter);
- }
- }
- else {
- // There are no samples queued for the loudspeaker. Don't wake upon its
- // buffer availability.
- if ( output_fd_base > 0 ) {
- poll_fd_count = output_fd_base;
- output_fd_base = -1;
- }
- }
+ wake_output(i->loudspeaker);
}
// FIX: Once everything else has been tested, make this program work with
drain_ssb(false);
}
+ void
+ Run::wake_output(AudioDevice * device)
+ {
+ if ( out_fifo.get_available() / 2 > 0 ) {
+ // There are samples queued for the loudspeaker/transmitter.
+ // Wake when there is room
+ // in its buffer.
+ if ( output_fd_base < 0 ) {
+ output_fd_base = poll_fd_count;
+ add_poll_device(device);
+ }
+ }
+ else {
+ // There are no samples queued for the loudspeaker/transmitter.
+ // Don't wake upon its buffer availability.
+ if ( output_fd_base > 0 ) {
+ poll_fd_count = output_fd_base;
+ output_fd_base = -1;
+ }
+ }
+ }
+
int
run(Interfaces * i)
{