/// the only reliable sample rate they all have in common. SampleRate
/// may be lower than that and thus there may be resampling in the
/// drivers.
- const unsigned int SampleRate = 8000;
+ const unsigned int SampleRate = 48000;
/// Allocate memory and copy a string into it, so that it is permanently
/// stored.
/// \param length The amount of data requested. This must be smaller
/// than or equal to the amount returned by get_available().
/// \return The address of the data to be read.
- inline const uint8_t * get(std::size_t length) {
+ inline const uint8_t *
+ get(std::size_t length) {
+ assert(length % 2 == 0);
if ( length > (std::size_t)(in - out) )
get_overrun();
return out;
/// This must be smaller than or equal to the amount passed to
/// get().
inline void get_done(std::size_t length) {
+ assert(length % 2 == 0);
out += length;
assert(out >= buffer && out <= buffer_end);
if ( out == in )
/// You must call put_done(length) when the I/O is completed.
/// The length passed to put_done() must be smaller than or equal
/// to the length passed to put().
- /// \param io_length The size of buffer in chars requested.
+ /// \param length The size of buffer in chars requested.
/// \return The address of the buffer for incoming data.
- inline uint8_t * put(std::size_t io_length) {
- const uint8_t * io_end = in + io_length;
+ inline uint8_t * put(std::size_t length) {
+ assert(length % 2 == 0);
+ const uint8_t * io_end = in + length;
if ( io_end > buffer_end )
- return reorder(io_length);
+ return reorder(length);
else
return in;
}
/// \param length The amount of data actually written. This must be
/// smaller than or equal to the length passed to put().
inline void put_done(std::size_t length) {
+ assert(length % 2 == 0);
in += length;
assert(in >= buffer && in <= buffer_end);
}
memcpy(o, i, length * 2);
*sample_length = length;
- return length;
+ return length * 2;
}
std::size_t
const unsigned int channels = 1;
const unsigned int rate = 48000;
const int soft_resample = 0;
- const unsigned int latency = 0;
+ const unsigned int latency = 10000;
int error;
handle = 0;
std::size_t
AudioOutALSA::write16(const std::int16_t * array, std::size_t length)
{
- // for ( std::size_t i = 0 ; i < length ; i++ )
- // std::cerr << array[i] << ' ';
-
int result = snd_pcm_writei(handle, array, length);
if ( result == -EPIPE ) {
snd_pcm_recover(handle, result, 1);
AudioOutALSA::ready()
{
snd_pcm_sframes_t available = 0;
+ snd_pcm_sframes_t delay = 0;
+ int error;
- available = snd_pcm_avail(handle);
- if ( available == -EPIPE ) {
- snd_pcm_recover(handle, available, 1);
- available = snd_pcm_avail(handle);
+ error = snd_pcm_avail_delay(handle, &available, &delay);
+ if ( error == -EPIPE ) {
+ snd_pcm_recover(handle, error, 1);
+ available = snd_pcm_avail_delay(handle, &available, &delay);
std::cerr << "ALSA write underrun." << std::endl;
}
- if ( available >= 0 )
+ if ( error == 0 )
return available;
- else if ( available == -EPIPE )
+ else if ( error == -EPIPE )
return 0;
else {
do_throw(available, "Get Frames Available for Write");
#include "drivers.h"
#include <unistd.h>
#include <iostream>
+#include <fstream>
#include <string.h>
/// FIX:
std::cerr << "Keying output is stalled." << std::endl;
}
}
-
+
// FIX: Parallelize the modem and codec into their own threads. Make the
// FIFO do locking.
void
(out_fifo.get_available() / 2));
if ( out_samples ) {
- std::int16_t * s = (std::int16_t *)out_fifo.get(out_samples * 2);
-
- for ( std::size_t i = 0; i < out_samples; i++ ) {
- std::cerr << (double)s[i] / 32767.0 << ' ';
- }
const std::size_t result = i->loudspeaker->write16(
(std::int16_t *)out_fifo.get(
out_samples * 2),
&samples_to_demodulate,
bytes_to_demodulate);
+
if ( samples_to_demodulate > 0 )
in_fifo.get_done(samples_to_demodulate * 2);
Run::run()
{
while ( true ) {
+ usleep(1000);
receive();
}
}
#define _USE_MATH_DEFINES
#include <cmath>
+
namespace FreeDV {
/// This is a test driver that provides tones.
class Tone : public AudioInput {
input++;
continue;
}
- if ( frequency < 0.0 || frequency > SampleRate ) {
+ if ( frequency < 0.0 || frequency > (SampleRate / 2) ) {
std::cerr << "tone: frequency must be in range of 0.0.."
<< SampleRate / 2 << ", is "
<< frequency << '.' << std::endl;
float sumOfAmplitudes = 0;
for ( unsigned int j = 0; j < array_length && tones[j].amplitude > 0.0;
j++ ) {
- value += (sine_wave(tones[j].frequency, i + clock)
+ value += (sine_wave(tones[j].frequency, clock + i)
* tones[j].amplitude);
// FIX: Hoist this out of the inner loop after it's tested.
sumOfAmplitudes += tones[j].amplitude;
// sum of amplitudes is 1.0.
if ( sumOfAmplitudes > 1.0 )
value /= sumOfAmplitudes;
- array[i] = (std::int16_t)rint(value * master_amplitude * ((1 << 15) - 1));
+ const std::int16_t v = (std::int16_t)rint(
+ value * master_amplitude * ((1 << 15) - 1));
+ array[i] = v;
}
clock = (clock + length) % SampleRate;