File: audio_sink.cpp

package info (click to toggle)
satdump 1.2.2%2Bgb79af48-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 81,648 kB
  • sloc: cpp: 276,768; ansic: 164,598; lisp: 1,219; sh: 283; xml: 106; makefile: 7
file content (79 lines) | stat: -rw-r--r-- 2,472 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "audio_sink.h"
#include "core/plugin.h"
#include "logger.h"

namespace audio
{
    std::map<std::string, std::function<std::shared_ptr<AudioSink>()>> sink_registry;

    AudioSink::AudioSink()
    {
    }

    class DummyAudioSink : public AudioSink
    {
    public:
        void set_samplerate(int) {}
        void start() {}
        void stop() {}

        void push_samples(int16_t *, int) {}

    public:
        static std::string getID() { return "dummy"; }
        static std::shared_ptr<AudioSink> getInstance() { return std::make_shared<DummyAudioSink>(); }
    };

    void registerSinks()
    {
        satdump::eventBus->fire_event<RegisterAudioSinkEvent>({sink_registry});
    }

    std::shared_ptr<AudioSink> get_default_sink()
    {
        if (sink_registry.count("portaudio"))
        {
            logger->info("Using PortAudio Sink");
            return sink_registry["portaudio"]();
        }
        else if (sink_registry.count("rtaudio"))
        {
            logger->info("Using RTAudio Sink");
            return sink_registry["rtaudio"]();
        }
        else
            return std::make_shared<DummyAudioSink>();
    }

    bool has_sink()
    {
        return sink_registry.size() > 0;
    }

    // https://github.com/cpuimage/resampler, just wanted something super basic
    int AudioSink::resample_s16(const int16_t *input, int16_t *output, int inSampleRate, int outSampleRate, int inputSize, int channels)
    {
        if (input == NULL)
            return 0;
        uint64_t outputSize = (uint64_t)(inputSize * (double)outSampleRate / (double)inSampleRate);
        outputSize -= outputSize % channels;
        if (output == NULL)
            return outputSize;
        double stepDist = ((double)inSampleRate / (double)outSampleRate);
        const uint64_t fixedFraction = (1LL << 32);
        const double normFixed = (1.0 / (1LL << 32));
        uint64_t step = ((uint64_t)(stepDist * fixedFraction + 0.5));
        uint64_t curOffset = 0;
        for (uint32_t i = 0; i < outputSize; i += 1)
        {
            for (int c = 0; c < channels; c += 1)
            {
                *output++ = (int16_t)(input[c] + (input[c + channels] - input[c]) * ((double)(curOffset >> 32) + ((curOffset & (fixedFraction - 1)) * normFixed)));
            }
            curOffset += step;
            input += (curOffset >> 32) * channels;
            curOffset &= (fixedFraction - 1);
        }
        return outputSize;
    }
}