aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcm/Traits.hxx
blob: 4e68191f6022ed03a9478c0c8029aef7a590db30 (plain) (blame)
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
/*
 * Copyright (C) 2003-2013 The Music Player Daemon Project
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef MPD_PCM_TRAITS_HXX
#define MPD_PCM_TRAITS_HXX

#include "check.h"
#include "AudioFormat.hxx"

#include <stdint.h>
#include <stddef.h>

/**
 * This template describes the specified #SampleFormat.  This is an
 * empty prototype; the specializations contain the real definitions.
 * See SampleTraits<uint8_t> for more documentation.
 */
template<SampleFormat F>
struct SampleTraits {};

template<>
struct SampleTraits<SampleFormat::S8> {
	/**
	 * The type used for one sample value.
	 */
	typedef int8_t value_type;

	/**
	 * A writable pointer.
	 */
	typedef value_type *pointer_type;

	/**
	 * A read-only pointer.
	 */
	typedef const value_type *const_pointer_type;

	/**
	 * A "long" type that is large and accurate enough for adding
	 * two values without risking an (integer) overflow or
	 * (floating point) precision loss.
	 */
	typedef int sum_type;

	/**
	 * A "long" type that is large and accurate enough for
	 * arithmetic without risking an (integer) overflow or
	 * (floating point) precision loss.
	 */
	typedef int_least16_t long_type;

	/**
	 * The size of one sample in bytes.
	 */
	static constexpr size_t SAMPLE_SIZE = sizeof(value_type);

	/**
	 * The integer bit depth of one sample.  This attribute may
	 * not exist if this is not an integer sample format.
	 */
	static constexpr unsigned BITS = sizeof(value_type) * 8;

	/**
	 * The minimum sample value.
	 */
	static constexpr value_type MIN = -(sum_type(1) << (BITS - 1));

	/**
	 * The maximum sample value.
	 */
	static constexpr value_type MAX = (sum_type(1) << (BITS - 1)) - 1;
};

template<>
struct SampleTraits<SampleFormat::S16> {
	typedef int16_t value_type;
	typedef value_type *pointer_type;
	typedef const value_type *const_pointer_type;

	typedef int_least32_t sum_type;
	typedef int_least32_t long_type;

	static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
	static constexpr unsigned BITS = sizeof(value_type) * 8;

	static constexpr value_type MIN = -(sum_type(1) << (BITS - 1));
	static constexpr value_type MAX = (sum_type(1) << (BITS - 1)) - 1;
};

template<>
struct SampleTraits<SampleFormat::S32> {
	typedef int32_t value_type;
	typedef value_type *pointer_type;
	typedef const value_type *const_pointer_type;

	typedef int_least64_t sum_type;
	typedef int_least64_t long_type;

	static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
	static constexpr unsigned BITS = sizeof(value_type) * 8;

	static constexpr value_type MIN = -(sum_type(1) << (BITS - 1));
	static constexpr value_type MAX = (sum_type(1) << (BITS - 1)) - 1;
};

template<>
struct SampleTraits<SampleFormat::S24_P32> {
	typedef int32_t value_type;
	typedef value_type *pointer_type;
	typedef const value_type *const_pointer_type;

	typedef int_least32_t sum_type;
	typedef int_least64_t long_type;

	static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
	static constexpr unsigned BITS = 24;

	static constexpr value_type MIN = -(sum_type(1) << (BITS - 1));
	static constexpr value_type MAX = (sum_type(1) << (BITS - 1)) - 1;
};

template<>
struct SampleTraits<SampleFormat::FLOAT> {
	typedef float value_type;
	typedef value_type *pointer_type;
	typedef const value_type *const_pointer_type;

	typedef float sum_type;
	typedef float long_type;

	static constexpr size_t SAMPLE_SIZE = sizeof(value_type);

	static constexpr value_type MIN = -1;
	static constexpr value_type MAX = 1;
};

#endif