summaryrefslogtreecommitdiffstats
path: root/src/encoder/encoder.cpp
blob: 8cee16a0ffe10d3c0a3dd69f60fe997fdf5d940b (plain)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "encoder/encoder.h"

#include <QList>

#include "preferences/usersettings.h"
#include "recording/defs_recording.h"
// TODO(XXX): __FFMPEGFILE_ENCODERS__ is currently undefined because
// FFMPEG encoders provide less features than the other encoders and currently
// we don't have a good fallback for using them. That's why it's a bad idea
// to have the worse encoders to take precedence over the good ones.
#ifdef __FFMPEGFILE_ENCODERS__
#include "encoder/encoderffmpegmp3.h"
#include "encoder/encoderffmpegvorbis.h"
#else
#include "encoder/encodermp3.h"
#include "encoder/encodervorbis.h"
#endif
#include "encoder/encoderwave.h"
#include "encoder/encodersndfileflac.h"

#include "encoder/encodermp3settings.h"
#include "encoder/encodervorbissettings.h"
#include "encoder/encoderwavesettings.h"
#include "encoder/encoderflacsettings.h"

#ifdef __OPUS__
#include "encoder/encoderopus.h"
#include "encoder/encoderopussettings.h"
#endif

#include "encoder/encoderfdkaac.h"
#include "encoder/encoderfdkaacsettings.h"

EncoderFactory EncoderFactory::factory;

const EncoderFactory& EncoderFactory::getFactory()
{
    return factory;
}

EncoderFactory::EncoderFactory() {
    // Add new supported formats here. Also modify the getNewEncoder/getEncoderSettings method.
    m_formats.append(Encoder::Format("WAV PCM", ENCODING_WAVE, true, "wav"));
    m_formats.append(Encoder::Format("AIFF PCM", ENCODING_AIFF, true, "aiff"));
    m_formats.append(Encoder::Format("FLAC", ENCODING_FLAC, true, "flac"));
    m_formats.append(Encoder::Format("MP3", ENCODING_MP3, false, "mp3"));
    m_formats.append(Encoder::Format("OGG Vorbis", ENCODING_OGG, false, "ogg"));
#ifdef __OPUS__
    m_formats.append(Encoder::Format("Opus", ENCODING_OPUS, false, "opus"));
#endif
    m_formats.append(Encoder::Format("AAC", ENCODING_AAC, false, "aac"));
    m_formats.append(Encoder::Format("HE-AAC", ENCODING_HEAAC, false, "aac"));
    m_formats.append(Encoder::Format("HE-AACv2", ENCODING_HEAACV2, false, "aac"));
}

const QList<Encoder::Format> EncoderFactory::getFormats() const
{
    return m_formats;
}

Encoder::Format EncoderFactory::getSelectedFormat(UserSettingsPointer pConfig) const
{
    return getFormatFor(pConfig->getValueString(ConfigKey(RECORDING_PREF_KEY, "Encoding")));
}
Encoder::Format EncoderFactory::getFormatFor(const QString& formatText) const {
    for (const auto& format : m_formats) {
        if (format.internalName == formatText) {
            return format;
        }
    }
    qWarning() << "Format: " << formatText << " not recognized! Returning format "
        << m_formats.first().internalName;
    return m_formats.first();
}

EncoderPointer EncoderFactory::createRecordingEncoder(
        const Encoder::Format& format,
        UserSettingsPointer pConfig,
        EncoderCallback* pCallback) const {
    EncoderRecordingSettingsPointer pSettings =
            getEncoderRecordingSettings(format, pConfig);
    return createEncoder(pSettings, pCallback);
}

EncoderPointer EncoderFactory::createEncoder(
        EncoderSettingsPointer pSettings,
        EncoderCallback* pCallback) const {
    EncoderPointer pEncoder;
    if (pSettings && pSettings->getFormat() == ENCODING_WAVE) {
        pEncoder = std::make_shared<EncoderWave>(pCallback);
        pEncoder->setEncoderSettings(*pSettings);
    } else if (pSettings && pSettings->getFormat() == ENCODING_AIFF) {
        pEncoder = std::make_shared<EncoderWave>(pCallback);
        pEncoder->setEncoderSettings(*pSettings);
    } else if (pSettings && pSettings->getFormat() == ENCODING_FLAC) {
        pEncoder = std::make_shared<EncoderSndfileFlac>(pCallback);
        pEncoder->setEncoderSettings(*pSettings);
    } else if (pSettings && pSettings->getFormat() == ENCODING_MP3) {
#ifdef __FFMPEGFILE_ENCODERS__
        pEncoder = std::make_shared<EncoderFfmpegMp3>(pCallback);
#else
        pEncoder = std::make_shared<EncoderMp3>(pCallback);
#endif
        pEncoder->setEncoderSettings(*pSettings);
    } else if (pSettings && pSettings->getFormat() == ENCODING_OGG) {
#ifdef __FFMPEGFILE_ENCODERS__
        pEncoder = std::make_shared<EncoderFfmpegVorbis>(pCallback);
#else
        pEncoder = std::make_shared<EncoderVorbis>(pCallback);
#endif
        pEncoder->setEncoderSettings(*pSettings);
#ifdef __OPUS__
    } else if (pSettings && pSettings->getFormat() == ENCODING_OPUS) {
        pEncoder = std::make_shared<EncoderOpus>(pCallback);
        pEncoder->setEncoderSettings(*pSettings);
#endif
    } else if (pSettings &&
            (pSettings->getFormat() == ENCODING_AAC ||
                    pSettings->getFormat() == ENCODING_HEAAC ||
                    pSettings->getFormat() == ENCODING_HEAACV2)) {
        pEncoder = std::make_shared<EncoderFdkAac>(pCallback);
        pEncoder->setEncoderSettings(*pSettings);
    } else {
        qWarning() << "Unsupported format requested! "
                << QString(pSettings ? pSettings->getFormat() : QString("NULL"));
        DEBUG_ASSERT(false);
        pEncoder = std::make_shared<EncoderWave>(pCallback);
    }
    return pEncoder;
}

EncoderRecordingSettingsPointer EncoderFactory::getEncoderRecordingSettings(Encoder::Format format,
        UserSettingsPointer pConfig) const {
    if (format.internalName == ENCODING_WAVE) {
        return std::make_shared<EncoderWaveSettings>(pConfig, format.internalName);
    } else if (format.internalName == ENCODING_AIFF) {
        return std::make_shared<EncoderWaveSettings>(pConfig, format.internalName);
    } else if (format.internalName == ENCODING_FLAC) {
        return std::make_shared<EncoderFlacSettings>(pConfig);
    } else if (format.internalName == ENCODING_MP3) {
        return std::make_shared<EncoderMp3Settings>(pConfig);
    } else if (format.internalName == ENCODING_OGG) {
        return std::make_shared<EncoderVorbisSettings>(pConfig);
#ifdef __OPUS__
    } else if (format.internalName == ENCODING_OPUS) {
        return std::make_shared<EncoderOpusSettings>(pConfig);
#endif
    } else if (format.internalName == ENCODING_AAC ||
            format.internalName == ENCODING_HEAAC ||
            format.internalName == ENCODING_HEAACV2) {
        return std::make_shared<EncoderFdkAacSettings>(pConfig, format.internalName);
    } else {
        qWarning() << "Unsupported format requested! " << format.internalName;
        DEBUG_ASSERT(false);
        return std::make_shared<EncoderWaveSettings>(pConfig, ENCODING_WAVE);
    }
}