summaryrefslogtreecommitdiffstats
path: root/src/converter.h
blob: 37c98f7bb45f684b096a24c703ac6d8939e372cd (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
#ifndef foosydneyconverterhfoo
#define foosydneyconverterhfoo

/***
  This file is part of libsydney.

  Copyright 2007-2008 Lennart Poettering

  libsydney is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation, either version 2.1 of the
  License, or (at your option) any later version.

  libsydney 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with libsydney. If not, see
  <http://www.gnu.org/licenses/>.
***/

#include "sydney.h"
#include "volscale.h"
#include "bswap.h"
#include "zero.h"
#include "add.h"
#include "bbuffer.h"
#include "resample.h"
#include "format.h"
#include "common.h"
#include "interleave.h"

typedef struct sa_converter sa_converter_t;

typedef enum {
    SA_INTERLEAVE_YES,                   /* samples are interleaved; left, right, left, right */
    SA_INTERLEAVE_NO,                    /* samples are managed in seperate blocks */
    SA_INTERLEAVE_ANY                    /* we don't care or don't know if the samples are interleaved or not */
} sa_interleave_t;

struct sa_converter {
    sa_pcm_format_t from_pcm_format, to_pcm_format;
    unsigned from_nchannels, to_nchannels;
    unsigned from_rate, to_rate;

    sa_bool_t sum_required;
    sa_bool_t remap_required;

    sa_bool_t no_volume;
    int32_t *volume_factor, *volume_divisor;

    sa_pcm_format_t work_pcm_format;

    size_t from_sample_size, work_sample_size, to_sample_size;

    sa_byteswap_func_t pre_byteswap_func, post_byteswap_func;
    sa_format_func_t pre_format_func, post_format_func;
    sa_volscale_func_t volscale_func;
    sa_zero_func_t zero_func;
    sa_add_func_t add_func;
    sa_resample_func_t resample_func;
    sa_interleave_func_t interleave_func;

    SpeexResamplerState *speex;

    sa_bbuffer_t bb_pre_byteswap,
        bb_pre_format,
        bb_volscale,
        bb_remap,
        bb_resample,
        bb_post_format,
        bb_post_byteswap,
        bb_interleave,
        bb_tmp;

    void **from_process_data, **to_process_data;
    size_t *from_stride, *to_stride;

    int *channel_map_table;

    void *zero_buffer;
    size_t zero_size;
};

int sa_converter_init(sa_converter_t *c, const pcm_attrs_t *from, const pcm_attrs_t *to, sa_bool_t dynamic_rate_enabled);
void sa_converter_done(sa_converter_t *c);

int sa_converter_go(
        sa_converter_t *c,
        const void *const src[], const size_t sstr[], sa_interleave_t sinterleave,
        void **dst[], size_t *dstr[], sa_interleave_t dinterleave,
        size_t *size);

int sa_converter_go_interleaved(
        sa_converter_t *c,
        const void *const data,
        void **dst[], size_t *dstr[], sa_interleave_t dinterleave,
        size_t *size);

void sa_converter_set_volume(sa_converter_t *c, const int32_t vol[]);

void sa_converter_set_ratio(sa_converter_t *c, unsigned rate1, unsigned rate2);

void* sa_converter_get_zero_buffer(sa_converter_t *c, size_t size);

#endif