예제 #1
0
void test_mixer(Mixer<double>& mixer)
{
    int N = 10;
    std::vector<double> a(N), b(N);
    for (int i = 0; i < N; i++)
    {
        a[i] = i + 1;
        b[i] = i + 2;
    }

    double beta = mixer.beta();
    printf("beta: %f\n", beta);

    for (int i = 0; i < N; i++) mixer.input_shared(i, a[i]);
    mixer.initialize();

    for (int i = 0; i < N; i++) mixer.input_shared(i, b[i]);

    mixer.mix();
    std::vector<double> c(N);

    for (int i = 0; i < N; i++) c[i] = mixer.output_shared(i);

    for (int i = 0; i < N; i++) printf("diff: %18.12f\n", std::abs(c[i] - (beta * b[i] + (1 - beta) * a[i])));
}
예제 #2
0
unsigned
MixerGroup::mix(float *outputs, unsigned space)
{
	Mixer	*mixer = _first;
	unsigned index = 0;

	while ((mixer != nullptr) && (index < space)) {
		index += mixer->mix(outputs + index, space - index);
		mixer = mixer->_next;
	}

	return index;
}
예제 #3
0
unsigned
MixerGroup::mix(float *outputs, unsigned space, uint16_t *status_reg)
{
	Mixer	*mixer = _first;
	unsigned index = 0;

	while ((mixer != NULL) && (index < space)) {
		index += mixer->mix(outputs + index, space - index, status_reg);
		mixer = mixer->_next;
	}

	return index;
}
예제 #4
0
int main(int argc, char **argv)
{
    int c;
    extern char *optarg;
    extern int optind __attribute__((unused));
    extern int optopt __attribute__((unused));
    extern int opterr;
    DSDcc::DSDDecoder dsdDecoder;
    DSDcc::DSDUpsampler upsamplingEngine;
    char in_file[1023];
    int  in_file_fd = -1;
    char out_file[1023];
    int  out_file_fd = -1;
    char log_file[1023];
    log_file[0] = '\0';
    char formattext_file[1023];
    formattext_file[0] = '\0';
    FILE *formattext_fp = 0;
    float formattext_refresh = 0.1f;
    char formattext[128];
    char serialDevice[16];
    std::string dvSerialDevice;
    int dvGain_dB = 0;
    int slots = 1;
    Mixer mixer;
    float lat = 0.0f;
    float lon = 0.0f;

    fprintf(stderr, "Digital Speech Decoder DSDcc\n");

    exitflag = 0;
    signal(SIGINT, sigfun);

    while ((c = getopt(argc, argv,
            "hHep:qtv:i:o:g:nR:f:u:U:lL:D:d:T:M:m:P:Q:x")) != -1)
    {
        opterr = 0;
        switch (c)
        {
        case 'h':
            usage();
            exit(0);
        case 'H':
            dsdDecoder.useHPMbelib(true);
            break;
        case 'e':
            dsdDecoder.showErrorBars();
            break;
        case 'p':
            if (optarg[0] == 'e')
            {
                dsdDecoder.setP25DisplayOptions(DSDcc::DSDDecoder::DSDShowP25EncryptionSyncBits, true);
            }
            else if (optarg[0] == 'l')
            {
                dsdDecoder.setP25DisplayOptions(DSDcc::DSDDecoder::DSDShowP25LinkControlBits, true);
            }
            else if (optarg[0] == 's')
            {
                dsdDecoder.setP25DisplayOptions(DSDcc::DSDDecoder::DSDShowP25EncryptionSyncBits, true);
            }
            else if (optarg[0] == 't')
            {
                dsdDecoder.setP25DisplayOptions(DSDcc::DSDDecoder::DSDShowP25TalkGroupInfo, true);
            }
            else if (optarg[0] == 'u')
            {
                dsdDecoder.muteEncryptedP25(false);
            }
            break;
        case 'q':
            dsdDecoder.setQuiet();
            break;
        case 't':
            dsdDecoder.showSymbolTiming();
            break;
        case 'v':
            int verbosity;
            sscanf(optarg, "%d", &verbosity);
            dsdDecoder.setLogVerbosity(verbosity);
            break;
        case 'L':
            strncpy(log_file, (const char *) optarg, 1023);
            log_file[1022] = '\0';
            break;
        case 'M':
            strncpy(formattext_file, (const char *) optarg, 1023);
            formattext_file[1022] = '\0';
            break;
        case 'm':
            float rate;
            sscanf(optarg, "%f", &rate);
            if (rate > 0.1f) {
                formattext_refresh = rate;
            }
            break;
        case 'i':
            strncpy(in_file, (const char *) optarg, 1023);
            in_file[1022] = '\0';
            break;
        case 'o':
            strncpy(out_file, (const char *) optarg, 1023);
            out_file[1022] = '\0';
            break;
#ifdef DSD_USE_SERIALDV
        case 'D':
            strncpy(serialDevice, (const char *) optarg, 16);
            serialDevice[15] = '\0';
            dvSerialDevice = serialDevice;
            break;
#endif
        case 'g':
            float gain;
            sscanf(optarg, "%f", &gain);
            dsdDecoder.setAudioGain(gain);
#ifdef DSD_USE_SERIALDV
            if (gain > 0) {
                dvGain_dB = (int) (10.0f * log10f(gain));
            }
#endif
            break;
        case 'n':
            dsdDecoder.enableAudioOut(false);
            break;
        case 'R':
            int resume;
            sscanf(optarg, "%d", &resume);
            dsdDecoder.enableScanResumeAfterTDULCFrames(resume);
            break;
        case 'd':
            int dataRateIndex;
            sscanf(optarg, "%d", &dataRateIndex);
            if ((dataRateIndex >= 0) && (dataRateIndex <= 2))
            {
                dsdDecoder.setDataRate((DSDcc::DSDDecoder::DSDRate) dataRateIndex);
            }
            break;
        case 'T':
            int tmpSlots;
            sscanf(optarg, "%d", &tmpSlots);
            if ((tmpSlots >= 0) && (tmpSlots <= 3))
            {
                slots = tmpSlots;
            }
            break;
        case 'f':
            dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeNone, true);
            if (optarg[0] == 'a') // auto detect
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeAuto, true);
            }
            else if (optarg[0] == 'r') // DMR/MOTOTRBO
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeDMR, true);
            }
            else if (optarg[0] == 'd') // D-Star
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeDStar, true);
            }
            else if (optarg[0] == 'x') // X2-TDMA
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeX2TDMA, true);
            }
            else if (optarg[0] == 'p') // ProVoice
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeProVoice, true);
            }
            else if (optarg[0] == '0') // P25 Phase 1
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeP25P1, true);
            }
            else if (optarg[0] == 'i') // NXDN48 IDAS
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeNXDN48, true);
            }
            else if (optarg[0] == 'n') // NXDN96
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeNXDN96, true);
            }
            else if (optarg[0] == 'm') // DPMR Tier 1 or 2
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeDPMR, true);
            }
            else if (optarg[0] == 'y') // YSF
            {
                dsdDecoder.setDecodeMode(DSDcc::DSDDecoder::DSDDecodeYSF, true);
            }
            break;
        case 'u':
            int uvquality;
            sscanf(optarg, "%i", &uvquality);
            dsdDecoder.setUvQuality(uvquality);
            break;
        case 'U':
            int upsampling;
            sscanf(optarg, "%d", &upsampling);
            dsdDecoder.setUpsampling(upsampling);
            break;
        case 'l':
            dsdDecoder.enableCosineFiltering(false);
            break;
        case 'P':
            sscanf(optarg, "%f", &lat);
            break;
        case 'Q':
            sscanf(optarg, "%f", &lon);
            break;
        case 'x':
            dsdDecoder.setSymbolPLLLock(false);
            break;
        default:
            usage();
            exit(0);
        }
    }

    dsdDecoder.setMyPoint(lat, lon);

    if (strlen(log_file) > 0) {
        dsdDecoder.setLogFile(log_file);
    }

    if (strncmp(in_file, (const char *) "-", 1) == 0)
    {
        in_file_fd = STDIN_FILENO;
    }
    else
    {
        in_file_fd = open(in_file, O_RDONLY);
    }

    if (in_file_fd > -1)
    {
        fprintf(stderr, "Opened %s for input.\n", in_file);
    }
    else
    {
        fprintf(stderr, "Cannot open %s for input. Aborting\n", in_file);
        return 0;
    }

    if (strncmp(out_file, (const char *) "-", 1) == 0)
    {
        out_file_fd = STDOUT_FILENO;
    }
    else
    {
        out_file_fd = open(out_file, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
    }

    if (out_file_fd > -1)
    {
        fprintf(stderr, "Opened %s for output.\n", in_file);
    }
    else
    {
        if (in_file_fd != STDIN_FILENO) {
            close(in_file_fd);
        }

        fprintf(stderr, "Cannot open %s for output. Aborting\n", out_file);
        return 0;
    }

#ifdef DSD_USE_SERIALDV
    SerialDV::DVController dvController;
    short dvAudioSamples[SerialDV::MBE_AUDIO_BLOCK_SIZE * 8];

    if (!dvSerialDevice.empty())
    {
        if (dvController.open(dvSerialDevice))
        {
            fprintf(stderr, "SerialDV up. Disable mbelib support\n");
            dsdDecoder.enableMbelib(false); // de-activate mbelib decoding
        }
    }
#endif

    int formattext_nsamples;

    if (formattext_file[0] == 0)
    {
        formattext_nsamples = 0;
    }
    else
    {
        formattext_nsamples = 48000.0f * formattext_refresh;
        formattext_fp = fopen(formattext_file, "w");

        if (!formattext_fp)
        {
            formattext_nsamples = 0;
        }
    }

    int formattext_sample_count = 0;

    while (exitflag == 0)
    {
        short sample;
        int nbAudioSamples1 = 0, nbAudioSamples2 = 0;
        short *audioSamples1, *audioSamples2;

        int result = read(in_file_fd, (void *) &sample, sizeof(short));

        if (result == 0)
        {
            fprintf(stderr, "No more input\n");
            break;
        }

        dsdDecoder.run(sample);

#ifdef DSD_USE_SERIALDV
        if (dvController.isOpen())
        {
            if (dsdDecoder.mbeDVReady1())
            {
                dvController.decode(dvAudioSamples, (const unsigned char *) dsdDecoder.getMbeDVFrame1(), (SerialDV::DVRate) dsdDecoder.getMbeRate(), dvGain_dB);

                if (dsdDecoder.upsampling())
                {
                    upsamplingEngine.upsample(dsdDecoder.upsampling(), dvAudioSamples, &dvAudioSamples[SerialDV::MBE_AUDIO_BLOCK_SIZE], SerialDV::MBE_AUDIO_BLOCK_SIZE);
                    result = write(out_file_fd, (const void *) &dvAudioSamples[SerialDV::MBE_AUDIO_BLOCK_SIZE], SerialDV::MBE_AUDIO_BLOCK_BYTES * dsdDecoder.upsampling());
                }
                else
                {
                    result = write(out_file_fd, (const void *) dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_BYTES); // TODO: upsampling
                }

                dsdDecoder.resetMbeDV1();
            }

            if (dsdDecoder.mbeDVReady2())
            {
                dvController.decode(dvAudioSamples, (const unsigned char *) dsdDecoder.getMbeDVFrame2(), (SerialDV::DVRate) dsdDecoder.getMbeRate(), dvGain_dB);

                if (dsdDecoder.upsampling())
                {
                    upsamplingEngine.upsample(dsdDecoder.upsampling(), dvAudioSamples, &dvAudioSamples[SerialDV::MBE_AUDIO_BLOCK_SIZE], SerialDV::MBE_AUDIO_BLOCK_SIZE);
                    result = write(out_file_fd, (const void *) &dvAudioSamples[SerialDV::MBE_AUDIO_BLOCK_SIZE], SerialDV::MBE_AUDIO_BLOCK_BYTES * dsdDecoder.upsampling());
                }
                else
                {
                    result = write(out_file_fd, (const void *) dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_BYTES); // TODO: upsampling
                }

                dsdDecoder.resetMbeDV2();
            }
        }
        else
#endif
        {
            if (slots & 1)
            {
                audioSamples1 = dsdDecoder.getAudio1(nbAudioSamples1);
            }

            if (slots & 2)
            {
                audioSamples2 = dsdDecoder.getAudio2(nbAudioSamples2);
            }

            if ((nbAudioSamples1 > 0) && (nbAudioSamples2 == 0))
            {
                result = write(out_file_fd, (const void *) audioSamples1, sizeof(short) * nbAudioSamples1);

                if (result < 0)
                {
                    fprintf(stderr, "Error writing to output\n");
                }
                else if ((unsigned int) result != sizeof(short) * nbAudioSamples1)
                {
                    fprintf(stderr, "Written %d out of %d audio samples\n", result/2, nbAudioSamples1);
                }

                dsdDecoder.resetAudio1();
            }

            if ((nbAudioSamples2 > 0) && (nbAudioSamples1 == 0))
            {
                result = write(out_file_fd, (const void *) audioSamples2, sizeof(short) * nbAudioSamples2);

                if (result < 0)
                {
                    fprintf(stderr, "Error writing to output\n");
                }
                else if ((unsigned int) result != sizeof(short) * nbAudioSamples2)
                {
                    fprintf(stderr, "Written %d out of %d audio samples\n", result/2, nbAudioSamples2);
                }

                dsdDecoder.resetAudio2();
            }

            if ((nbAudioSamples1 > 0) && (nbAudioSamples2 > 0))
            {
                short *mix;
                int mixSize;

                mixer.mix(nbAudioSamples1, nbAudioSamples2, audioSamples1, audioSamples2);
                mix = mixer.getMix(mixSize);

                result = write(out_file_fd, (const void *) mix, sizeof(short) * mixSize);

                if (result < 0)
                {
                    fprintf(stderr, "Error writing to output\n");
                }
                else if ((unsigned int) result != sizeof(short) * mixSize)
                {
                    fprintf(stderr, "Written %d out of %d audio samples\n", result/2, mixSize);
                }

                dsdDecoder.resetAudio1();
                dsdDecoder.resetAudio2();
            }
        }

        if (formattext_nsamples > 0)
        {
            if (formattext_sample_count < formattext_nsamples)
            {
                formattext_sample_count++;
            }
            else
            {
                dsdDecoder.formatStatusText(formattext);
                fputs(formattext, formattext_fp);
                putc('\n', formattext_fp);
                formattext_sample_count = 0;
            }
        }
    }

    if (formattext_fp)
    {
        fclose(formattext_fp);
    }

    fprintf(stderr, "End of process\n");

#ifdef DSD_USE_SERIALDV
    if (dvController.isOpen()) {
        dvController.close();
    }
#endif

    if ((out_file_fd > -1) && (out_file_fd != STDOUT_FILENO)) {
        close(out_file_fd);
    }

    if ((in_file_fd > -1) && (in_file_fd != STDIN_FILENO)) {
        close(in_file_fd);
    }

    return (0);
}