Handle streams separately in tree_add_track()
[cmus.git] / pcm.c
blob17d92326247408827d4f5e9059dd409cbbe0b50d
1 #include "pcm.h"
3 #include <inttypes.h>
4 #include <stdlib.h>
6 /*
7 * Functions to convert PCM to 16-bit signed little-endian stereo
9 * Conversion for 8-bit PCM):
10 * 1. phase
11 * unsigned -> signed
12 * mono -> stereo
13 * 8 -> 16
15 * Conversion for 16-bit PCM:
16 * 1. phase
17 * be -> le
18 * unsigned -> signed
20 * 2. phase
21 * mono -> stereo
23 * There's no reason to split 8-bit conversion to 2 phases because we need to
24 * use separate buffer for 8->16 conversion anyway.
26 * Conversions for 16-bit stereo can be done in place. 16-bit mono needs to be
27 * converted to stereo so it's worthwhile to split the conversion to 2 phases.
30 static void convert_u8_1ch_to_s16_2ch(char *dst, const char *src, int count)
32 int16_t *d = (int16_t *)dst;
33 const uint8_t *s = (const uint8_t *)src;
34 int i, j = 0;
36 for (i = 0; i < count; i++) {
37 int16_t sample = s[i] << 8;
38 sample -= 32768;
39 d[j++] = sample;
40 d[j++] = sample;
44 static void convert_s8_1ch_to_s16_2ch(char *dst, const char *src, int count)
46 int16_t *d = (int16_t *)dst;
47 const int8_t *s = (const int8_t *)src;
48 int i, j = 0;
50 for (i = 0; i < count; i++) {
51 int16_t sample = s[i] << 8;
52 d[j++] = sample;
53 d[j++] = sample;
57 static void convert_u8_2ch_to_s16_2ch(char *dst, const char *src, int count)
59 int16_t *d = (int16_t *)dst;
60 const int8_t *s = (const int8_t *)src;
61 int i;
63 for (i = 0; i < count; i++) {
64 int16_t sample = s[i] << 8;
65 sample -= 32768;
66 d[i] = sample;
70 static void convert_s8_2ch_to_s16_2ch(char *dst, const char *src, int count)
72 int16_t *d = (int16_t *)dst;
73 const int8_t *s = (const int8_t *)src;
74 int i;
76 for (i = 0; i < count; i++) {
77 int16_t sample = s[i] << 8;
78 d[i] = sample;
82 static void convert_u16_le_to_s16_le(char *buf, int count)
84 int16_t *b = (int16_t *)buf;
85 int i;
87 for (i = 0; i < count; i++) {
88 int sample = (uint16_t)b[i];
89 sample -= 32768;
90 b[i] = sample;
94 static void convert_u16_be_to_s16_le(char *buf, int count)
96 int16_t *b = (int16_t *)buf;
97 int i;
99 for (i = 0; i < count; i++) {
100 uint16_t u = b[i];
101 int sample;
103 u = (u << 8) | (u >> 8);
104 sample = (int)u - 32768;
105 b[i] = sample;
109 static void convert_s16_be_to_s16_le(char *buf, int count)
111 int16_t *b = (int16_t *)buf;
112 int i;
114 for (i = 0; i < count; i++) {
115 uint16_t sample = b[i];
116 b[i] = (sample << 8) | (sample >> 8);
120 static void convert_16_1ch_to_16_2ch(char *dst, const char *src, int count)
122 int16_t *d = (int16_t *)dst;
123 const int16_t *s = (const int16_t *)src;
124 int i, j = 0;
126 for (i = 0; i < count; i++) {
127 d[j++] = s[i];
128 d[j++] = s[i];
132 /* index is ((bits >> 2) & 4) | (is_signed << 1) | (channels - 1) */
133 pcm_conv_func pcm_conv[8] = {
134 convert_u8_1ch_to_s16_2ch,
135 convert_u8_2ch_to_s16_2ch,
136 convert_s8_1ch_to_s16_2ch,
137 convert_s8_2ch_to_s16_2ch,
139 convert_16_1ch_to_16_2ch,
140 NULL,
141 convert_16_1ch_to_16_2ch,
142 NULL
145 /* index is ((bits >> 2) & 4) | (is_signed << 1) | bigendian */
146 pcm_conv_in_place_func pcm_conv_in_place[8] = {
147 NULL,
148 NULL,
149 NULL,
150 NULL,
152 convert_u16_le_to_s16_le,
153 convert_u16_be_to_s16_le,
154 NULL,
155 convert_s16_be_to_s16_le