mirror of https://github.com/wb2osz/direwolf.git
build under ALSA
This commit is contained in:
parent
52bf2ff5bd
commit
99e7095f17
10
audio.h
10
audio.h
|
@ -35,6 +35,12 @@ enum ptt_method_e {
|
||||||
|
|
||||||
typedef enum ptt_method_e ptt_method_t;
|
typedef enum ptt_method_e ptt_method_t;
|
||||||
|
|
||||||
|
enum ptt_audio_state_e {
|
||||||
|
PTT_AUDIO_STATE_STOP,
|
||||||
|
PTT_AUDIO_STATE_START,
|
||||||
|
PTT_AUDIO_STATE_CLOSE };
|
||||||
|
typedef enum ptt_audio_state_e ptt_audio_state_t;
|
||||||
|
|
||||||
enum ptt_line_e { PTT_LINE_NONE = 0, PTT_LINE_RTS = 1, PTT_LINE_DTR = 2 }; // Important: 0 for neither.
|
enum ptt_line_e { PTT_LINE_NONE = 0, PTT_LINE_RTS = 1, PTT_LINE_DTR = 2 }; // Important: 0 for neither.
|
||||||
typedef enum ptt_line_e ptt_line_t;
|
typedef enum ptt_line_e ptt_line_t;
|
||||||
|
|
||||||
|
@ -203,7 +209,9 @@ struct audio_s {
|
||||||
HANDLE ptt_stop; /* Handle for event that stops ptt tone. */
|
HANDLE ptt_stop; /* Handle for event that stops ptt tone. */
|
||||||
HANDLE ptt_close; /* Handle for event that closes ptt. */
|
HANDLE ptt_close; /* Handle for event that closes ptt. */
|
||||||
#else
|
#else
|
||||||
|
pthread_mutex_t ptt_mutex; /* Mutex for controlling ptt tone state. */
|
||||||
|
pthread_cond_t ptt_condition; /* Condition for controlling ptt tone state. */
|
||||||
|
ptt_audio_state_t ptt_state; /* State of ptt tone. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_HAMLIB
|
#ifdef USE_HAMLIB
|
||||||
|
|
64
audio_ptt.c
64
audio_ptt.c
|
@ -91,7 +91,6 @@ static void * ptt_thread (void *arg)
|
||||||
|
|
||||||
err = snd_pcm_open(&handle, save_audio_config_p->adev[a].adevice_out, SND_PCM_STREAM_PLAYBACK, 0);
|
err = snd_pcm_open(&handle, save_audio_config_p->adev[a].adevice_out, SND_PCM_STREAM_PLAYBACK, 0);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
snd_pcm_sframes_t frames;
|
|
||||||
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
|
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
|
||||||
|
|
||||||
err = snd_pcm_set_params(handle, format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
err = snd_pcm_set_params(handle, format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||||
|
@ -100,57 +99,55 @@ static void * ptt_thread (void *arg)
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
short* pnData;
|
short* pnData;
|
||||||
short sample;
|
short sample;
|
||||||
int nSamples = save_audio_config_p->adev[a].samples_per_sec / 10;
|
int nSamples = save_audio_config_p->adev[a].samples_per_sec / 5;
|
||||||
int nBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof(short);
|
int nBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof(short);
|
||||||
int i;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
pnData = (short*)malloc (nBufferLength);
|
pnData = (short*)malloc (nBufferLength);
|
||||||
|
|
||||||
if (save_audio_config_p->adev[a].num_channels == 1) {
|
|
||||||
for (i = 0; i < nSamples; i++) {
|
for (i = 0; i < nSamples; i++) {
|
||||||
sample = (short)( (double)SHRT_MAX * sin( ( (double)i * freq / (double)save_audio_config_p->adev[a].samples_per_sec ) * 2.0 * M_PI ) );
|
sample = (short)( (double)SHRT_MAX * sin( ( (double)i * freq / (double)save_audio_config_p->adev[a].samples_per_sec ) * 2.0 * M_PI ) );
|
||||||
pnData[i] = sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (i = 0; i < nSamples; i++) {
|
|
||||||
sample = (short)( (double)SHRT_MAX * sin( ( (double)i * freq / (double)save_audio_config_p->adev[a].samples_per_sec ) * 2.0 * M_PI ) );
|
|
||||||
if (channel == ADEVFIRSTCHAN( a )) {
|
|
||||||
|
|
||||||
// Stereo, left channel.
|
for (j = 0; j < save_audio_config_p->adev[a].num_channels; j++) {
|
||||||
|
if (channel == ADEVFIRSTCHAN( a ) + j) {
|
||||||
pnData[i*2 + 0] = sample;
|
pnData[i*save_audio_config_p->adev[a].num_channels + j] = sample;
|
||||||
pnData[i*2 + 1] = 0;
|
} else {
|
||||||
}
|
pnData[i*save_audio_config_p->adev[a].num_channels + j] = 0;
|
||||||
else {
|
|
||||||
|
|
||||||
// Stereo, right channel.
|
|
||||||
|
|
||||||
pnData[i*2 + 0] = 0;
|
|
||||||
pnData[i*2 + 1] = sample;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
while (1) {
|
||||||
// ptt_set on
|
pthread_mutex_lock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
//
|
ptt_audio_state_t ptt_state = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_state;
|
||||||
|
pthread_mutex_unlock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
|
|
||||||
for (i=0; i<50; i++) {
|
if (ptt_state == PTT_AUDIO_STATE_STOP) {
|
||||||
frames = snd_pcm_writei(handle, pnData, nSamples);
|
snd_pcm_drop (handle);
|
||||||
|
|
||||||
|
pthread_mutex_lock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
|
pthread_cond_wait (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_condition, &save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
|
ptt_state = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_state;
|
||||||
|
pthread_mutex_unlock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
|
|
||||||
|
if (ptt_state == PTT_AUDIO_STATE_START) {
|
||||||
|
snd_pcm_prepare (handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
if (ptt_state == PTT_AUDIO_STATE_START) {
|
||||||
// ptt_set off
|
snd_pcm_writei (handle, pnData, nSamples);
|
||||||
//
|
}
|
||||||
|
else if (ptt_state == PTT_AUDIO_STATE_CLOSE) {
|
||||||
|
snd_pcm_drop (handle);
|
||||||
|
|
||||||
//
|
break;
|
||||||
// close
|
}
|
||||||
//
|
}
|
||||||
|
|
||||||
free (pnData);
|
free (pnData);
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_close (handle);
|
snd_pcm_close (handle);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -165,3 +162,4 @@ static void * ptt_thread (void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ unsigned __stdcall ptt_thread (void *arg)
|
||||||
short sample;
|
short sample;
|
||||||
int nSamples = save_audio_config_p->adev[a].samples_per_sec / freq;
|
int nSamples = save_audio_config_p->adev[a].samples_per_sec / freq;
|
||||||
int i;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
waveHeader.dwBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof( short );
|
waveHeader.dwBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof( short );
|
||||||
waveHeader.lpData = malloc( waveHeader.dwBufferLength );
|
waveHeader.lpData = malloc( waveHeader.dwBufferLength );
|
||||||
|
@ -109,28 +110,14 @@ unsigned __stdcall ptt_thread (void *arg)
|
||||||
|
|
||||||
pnData = (short*)waveHeader.lpData;
|
pnData = (short*)waveHeader.lpData;
|
||||||
|
|
||||||
if( save_audio_config_p->adev[a].num_channels == 1 ) {
|
|
||||||
for (i = 0; i < nSamples; i++) {
|
for (i = 0; i < nSamples; i++) {
|
||||||
sample = (short)( (double)SHRT_MAX * sin( ( (double)i / (double)nSamples ) * 2.0 * M_PI ) );
|
sample = (short)( (double)SHRT_MAX * sin( ( (double)i / (double)nSamples ) * 2.0 * M_PI ) );
|
||||||
pnData[i] = sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for( i = 0; i < nSamples; i++ ) {
|
|
||||||
sample = (short)( (double)SHRT_MAX * sin( ( (double)i / (double)nSamples ) * 2.0 * M_PI ) );
|
|
||||||
if( channel == ADEVFIRSTCHAN( a ) ) {
|
|
||||||
|
|
||||||
// Stereo, left channel.
|
for (j = 0; j < save_audio_config_p->adev[a].num_channels; j++) {
|
||||||
|
if (channel == ADEVFIRSTCHAN( a ) + j) {
|
||||||
pnData[i*2 + 0] = sample;
|
pnData[i*save_audio_config_p->adev[a].num_channels + j] = sample;
|
||||||
pnData[i*2 + 1] = 0;
|
} else {
|
||||||
}
|
pnData[i*save_audio_config_p->adev[a].num_channels + j] = 0;
|
||||||
else {
|
|
||||||
|
|
||||||
// Stereo, right channel.
|
|
||||||
|
|
||||||
pnData[i*2 + 0] = 0;
|
|
||||||
pnData[i*2 + 1] = sample;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,24 +135,21 @@ unsigned __stdcall ptt_thread (void *arg)
|
||||||
{
|
{
|
||||||
dwWait = WaitForMultipleObjects (3, handles, FALSE, INFINITE);
|
dwWait = WaitForMultipleObjects (3, handles, FALSE, INFINITE);
|
||||||
|
|
||||||
if( dwWait == WAIT_OBJECT_0 + 0 )
|
if (dwWait == WAIT_OBJECT_0 + 0) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// ptt_set on
|
// ptt_set on
|
||||||
//
|
//
|
||||||
|
|
||||||
waveOutWrite ( hWaveOut, &waveHeader, sizeof( WAVEHDR ) );
|
waveOutWrite ( hWaveOut, &waveHeader, sizeof( WAVEHDR ) );
|
||||||
}
|
}
|
||||||
else if( dwWait == WAIT_OBJECT_0 + 1 )
|
else if (dwWait == WAIT_OBJECT_0 + 1) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// ptt_set off
|
// ptt_set off
|
||||||
//
|
//
|
||||||
|
|
||||||
waveOutReset ( hWaveOut );
|
waveOutReset ( hWaveOut );
|
||||||
}
|
}
|
||||||
else if( dwWait == WAIT_OBJECT_0 + 2 )
|
else if( dwWait == WAIT_OBJECT_0 + 2 ) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// close
|
// close
|
||||||
//
|
//
|
||||||
|
|
4
config.c
4
config.c
|
@ -673,6 +673,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
p_audio_config->achan[channel].octrl[ot].ptt_stop = NULL;
|
p_audio_config->achan[channel].octrl[ot].ptt_stop = NULL;
|
||||||
p_audio_config->achan[channel].octrl[ot].ptt_close = NULL;
|
p_audio_config->achan[channel].octrl[ot].ptt_close = NULL;
|
||||||
#else
|
#else
|
||||||
|
p_audio_config->achan[channel].octrl[ot].ptt_state = PTT_AUDIO_STATE_STOP;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1635,6 +1636,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
p_audio_config->achan[channel].octrl[ot].ptt_stop = CreateEvent (NULL, FALSE, FALSE, NULL);
|
p_audio_config->achan[channel].octrl[ot].ptt_stop = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
p_audio_config->achan[channel].octrl[ot].ptt_close = CreateEvent (NULL, FALSE, FALSE, NULL);
|
p_audio_config->achan[channel].octrl[ot].ptt_close = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
#else
|
#else
|
||||||
|
p_audio_config->achan[channel].octrl[ot].ptt_state = PTT_AUDIO_STATE_STOP;
|
||||||
|
pthread_mutex_init(&p_audio_config->achan[channel].octrl[ot].ptt_mutex, 0);
|
||||||
|
pthread_cond_init(&p_audio_config->achan[channel].octrl[ot].ptt_condition, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
14
ptt.c
14
ptt.c
|
@ -1015,7 +1015,10 @@ void ptt_set (int ot, int chan, int ptt_signal)
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
SetEvent (save_audio_config_p->achan[chan].octrl[ot].ptt_start);
|
SetEvent (save_audio_config_p->achan[chan].octrl[ot].ptt_start);
|
||||||
#else
|
#else
|
||||||
|
pthread_mutex_lock (&save_audio_config_p->achan[chan].octrl[ot].ptt_mutex);
|
||||||
|
save_audio_config_p->achan[chan].octrl[ot].ptt_state = PTT_AUDIO_STATE_START;
|
||||||
|
pthread_cond_signal (&save_audio_config_p->achan[chan].octrl[ot].ptt_condition);
|
||||||
|
pthread_mutex_unlock (&save_audio_config_p->achan[chan].octrl[ot].ptt_mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1023,7 +1026,9 @@ void ptt_set (int ot, int chan, int ptt_signal)
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
SetEvent (save_audio_config_p->achan[chan].octrl[ot].ptt_stop);
|
SetEvent (save_audio_config_p->achan[chan].octrl[ot].ptt_stop);
|
||||||
#else
|
#else
|
||||||
|
pthread_mutex_lock (&save_audio_config_p->achan[chan].octrl[ot].ptt_mutex);
|
||||||
|
save_audio_config_p->achan[chan].octrl[ot].ptt_state = PTT_AUDIO_STATE_STOP;
|
||||||
|
pthread_mutex_unlock (&save_audio_config_p->achan[chan].octrl[ot].ptt_mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1137,7 +1142,10 @@ void ptt_term (void)
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
SetEvent (save_audio_config_p->achan[n].octrl[OCTYPE_PTT].ptt_close) ;
|
SetEvent (save_audio_config_p->achan[n].octrl[OCTYPE_PTT].ptt_close) ;
|
||||||
#else
|
#else
|
||||||
|
pthread_mutex_lock (&save_audio_config_p->achan[n].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
|
save_audio_config_p->achan[n].octrl[OCTYPE_PTT].ptt_state = PTT_AUDIO_STATE_CLOSE;
|
||||||
|
pthread_cond_signal (&save_audio_config_p->achan[n].octrl[OCTYPE_PTT].ptt_condition);
|
||||||
|
pthread_mutex_unlock (&save_audio_config_p->achan[n].octrl[OCTYPE_PTT].ptt_mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue