mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-25 20:22:10 -05:00
383 lines
9.4 KiB
C
383 lines
9.4 KiB
C
/*
|
|
* Copyright (C) 2010 DSD Author
|
|
* GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "dsd.h"
|
|
#include "dmr_const.h"
|
|
|
|
void
|
|
processDMRvoice (dsd_opts * opts, dsd_state * state)
|
|
{
|
|
// extracts AMBE frames from DMR frame
|
|
int i, j, dibit;
|
|
int *dibit_p;
|
|
char ambe_fr[4][24];
|
|
char ambe_fr2[4][24];
|
|
char ambe_fr3[4][24];
|
|
const int *w, *x, *y, *z;
|
|
char sync[25];
|
|
char syncdata[25];
|
|
char cachdata[13];
|
|
int mutecurrentslot;
|
|
int msMode;
|
|
|
|
#ifdef DMR_DUMP
|
|
int k;
|
|
char syncbits[49];
|
|
char cachbits[25];
|
|
#endif
|
|
|
|
mutecurrentslot = 0;
|
|
msMode = 0;
|
|
|
|
dibit_p = state->dibit_buf_p - 144;
|
|
for (j = 0; j < 6; j++)
|
|
{
|
|
// 2nd half of previous slot
|
|
for (i = 0; i < 54; i++)
|
|
{
|
|
if (j > 0)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
}
|
|
else
|
|
{
|
|
dibit = *dibit_p;
|
|
dibit_p++;
|
|
if (opts->inverted_dmr == 1)
|
|
{
|
|
dibit = (dibit ^ 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
// CACH
|
|
for (i = 0; i < 12; i++)
|
|
{
|
|
if (j > 0)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
}
|
|
else
|
|
{
|
|
dibit = *dibit_p;
|
|
dibit_p++;
|
|
if (opts->inverted_dmr == 1)
|
|
{
|
|
dibit = (dibit ^ 2);
|
|
}
|
|
}
|
|
cachdata[i] = dibit;
|
|
if (i == 2)
|
|
{
|
|
state->currentslot = (1 & (dibit >> 1)); // bit 1
|
|
if (state->currentslot == 0)
|
|
{
|
|
state->slot0light[0] = '[';
|
|
state->slot0light[6] = ']';
|
|
state->slot1light[0] = ' ';
|
|
state->slot1light[6] = ' ';
|
|
}
|
|
else
|
|
{
|
|
state->slot1light[0] = '[';
|
|
state->slot1light[6] = ']';
|
|
state->slot0light[0] = ' ';
|
|
state->slot0light[6] = ' ';
|
|
}
|
|
}
|
|
}
|
|
cachdata[12] = 0;
|
|
|
|
|
|
#ifdef DMR_DUMP
|
|
k = 0;
|
|
for (i = 0; i < 12; i++)
|
|
{
|
|
dibit = cachdata[i];
|
|
cachbits[k] = (1 & (dibit >> 1)) + 48; // bit 1
|
|
k++;
|
|
cachbits[k] = (1 & dibit) + 48; // bit 0
|
|
k++;
|
|
}
|
|
cachbits[24] = 0;
|
|
fprintf(stderr, "%s ", cachbits);
|
|
#endif
|
|
|
|
// current slot frame 1
|
|
w = rW;
|
|
x = rX;
|
|
y = rY;
|
|
z = rZ;
|
|
for (i = 0; i < 36; i++)
|
|
{
|
|
if (j > 0)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
}
|
|
else
|
|
{
|
|
dibit = *dibit_p;
|
|
dibit_p++;
|
|
if (opts->inverted_dmr == 1)
|
|
{
|
|
dibit = (dibit ^ 2);
|
|
}
|
|
}
|
|
ambe_fr[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
|
ambe_fr[*y][*z] = (1 & dibit); // bit 0
|
|
w++;
|
|
x++;
|
|
y++;
|
|
z++;
|
|
}
|
|
|
|
// current slot frame 2 first half
|
|
w = rW;
|
|
x = rX;
|
|
y = rY;
|
|
z = rZ;
|
|
for (i = 0; i < 18; i++)
|
|
{
|
|
if (j > 0)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
}
|
|
else
|
|
{
|
|
dibit = *dibit_p;
|
|
dibit_p++;
|
|
if (opts->inverted_dmr == 1)
|
|
{
|
|
dibit = (dibit ^ 2);
|
|
}
|
|
}
|
|
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
|
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
|
w++;
|
|
x++;
|
|
y++;
|
|
z++;
|
|
}
|
|
|
|
// signaling data or sync
|
|
for (i = 0; i < 24; i++)
|
|
{
|
|
if (j > 0)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
}
|
|
else
|
|
{
|
|
dibit = *dibit_p;
|
|
dibit_p++;
|
|
if (opts->inverted_dmr == 1)
|
|
{
|
|
dibit = (dibit ^ 2);
|
|
}
|
|
}
|
|
syncdata[i] = dibit;
|
|
sync[i] = (dibit | 1) + 48;
|
|
}
|
|
sync[24] = 0;
|
|
syncdata[24] = 0;
|
|
|
|
if ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
|
|
{
|
|
mutecurrentslot = 1;
|
|
if (state->currentslot == 0)
|
|
{
|
|
sprintf (state->slot0light, "[slot0]");
|
|
}
|
|
else
|
|
{
|
|
sprintf (state->slot1light, "[slot1]");
|
|
}
|
|
}
|
|
else if ((strcmp (sync, DMR_BS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_VOICE_SYNC) == 0))
|
|
{
|
|
mutecurrentslot = 0;
|
|
if (state->currentslot == 0)
|
|
{
|
|
sprintf (state->slot0light, "[SLOT0]");
|
|
}
|
|
else
|
|
{
|
|
sprintf (state->slot1light, "[SLOT1]");
|
|
}
|
|
}
|
|
if ((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) || (strcmp (sync, DMR_MS_DATA_SYNC) == 0))
|
|
{
|
|
msMode = 1;
|
|
}
|
|
|
|
if ((j == 0) && (opts->errorbars == 1))
|
|
{
|
|
fprintf(stderr, "%s %s VOICE e:", state->slot0light, state->slot1light);
|
|
}
|
|
|
|
#ifdef DMR_DUMP
|
|
k = 0;
|
|
for (i = 0; i < 24; i++)
|
|
{
|
|
dibit = syncdata[i];
|
|
syncbits[k] = (1 & (dibit >> 1)) + 48; // bit 1
|
|
k++;
|
|
syncbits[k] = (1 & dibit) + 48; // bit 0
|
|
k++;
|
|
}
|
|
syncbits[48] = 0;
|
|
fprintf(stderr, "%s ", syncbits);
|
|
#endif
|
|
|
|
// current slot frame 2 second half
|
|
for (i = 0; i < 18; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
ambe_fr2[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
|
ambe_fr2[*y][*z] = (1 & dibit); // bit 0
|
|
w++;
|
|
x++;
|
|
y++;
|
|
z++;
|
|
}
|
|
|
|
if (mutecurrentslot == 0)
|
|
{
|
|
if (state->firstframe == 1)
|
|
{ // we don't know if anything received before the first sync after no carrier is valid
|
|
state->firstframe = 0;
|
|
}
|
|
else
|
|
{
|
|
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
|
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
|
}
|
|
}
|
|
|
|
// current slot frame 3
|
|
w = rW;
|
|
x = rX;
|
|
y = rY;
|
|
z = rZ;
|
|
for (i = 0; i < 36; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
ambe_fr3[*w][*x] = (1 & (dibit >> 1)); // bit 1
|
|
ambe_fr3[*y][*z] = (1 & dibit); // bit 0
|
|
w++;
|
|
x++;
|
|
y++;
|
|
z++;
|
|
}
|
|
if (mutecurrentslot == 0)
|
|
{
|
|
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
|
}
|
|
|
|
// CACH
|
|
for (i = 0; i < 12; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
cachdata[i] = dibit;
|
|
}
|
|
cachdata[12] = 0;
|
|
|
|
#ifdef DMR_DUMP
|
|
k = 0;
|
|
for (i = 0; i < 12; i++)
|
|
{
|
|
dibit = cachdata[i];
|
|
cachbits[k] = (1 & (dibit >> 1)) + 48; // bit 1
|
|
k++;
|
|
cachbits[k] = (1 & dibit) + 48; // bit 0
|
|
k++;
|
|
}
|
|
cachbits[24] = 0;
|
|
fprintf(stderr, "%s ", cachbits);
|
|
#endif
|
|
|
|
|
|
// next slot
|
|
skipDibit (opts, state, 54);
|
|
|
|
// signaling data or sync
|
|
for (i = 0; i < 24; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
syncdata[i] = dibit;
|
|
sync[i] = (dibit | 1) + 48;
|
|
}
|
|
sync[24] = 0;
|
|
syncdata[24] = 0;
|
|
|
|
if ((strcmp (sync, DMR_BS_DATA_SYNC) == 0) || (msMode == 1))
|
|
{
|
|
if (state->currentslot == 0)
|
|
{
|
|
sprintf (state->slot1light, " slot1 ");
|
|
}
|
|
else
|
|
{
|
|
sprintf (state->slot0light, " slot0 ");
|
|
}
|
|
}
|
|
else if (strcmp (sync, DMR_BS_VOICE_SYNC) == 0)
|
|
{
|
|
if (state->currentslot == 0)
|
|
{
|
|
sprintf (state->slot1light, " SLOT1 ");
|
|
}
|
|
else
|
|
{
|
|
sprintf (state->slot0light, " SLOT0 ");
|
|
}
|
|
}
|
|
|
|
#ifdef DMR_DUMP
|
|
k = 0;
|
|
for (i = 0; i < 24; i++)
|
|
{
|
|
dibit = syncdata[i];
|
|
syncbits[k] = (1 & (dibit >> 1)) + 48; // bit 1
|
|
k++;
|
|
syncbits[k] = (1 & dibit) + 48; // bit 0
|
|
k++;
|
|
}
|
|
syncbits[48] = 0;
|
|
fprintf(stderr, "%s ", syncbits);
|
|
#endif
|
|
|
|
if (j == 5)
|
|
{
|
|
// 2nd half next slot
|
|
skipDibit (opts, state, 54);
|
|
|
|
// CACH
|
|
skipDibit (opts, state, 12);
|
|
|
|
// first half current slot
|
|
skipDibit (opts, state, 54);
|
|
}
|
|
}
|
|
|
|
if (opts->errorbars == 1)
|
|
{
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
}
|