-
Notifications
You must be signed in to change notification settings - Fork 1
/
stream_decoder_helpers.c
84 lines (72 loc) · 2.23 KB
/
stream_decoder_helpers.c
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
#include "stream_decoder_helpers.h"
static unsigned round_to_bytes(unsigned bits)
{
return (bits + (bits % 8)) / 8;
}
static FLAC__StreamDecoderWriteStatus write_callback
( const FLAC__StreamDecoder *decoder
, const FLAC__Frame *frame
, const FLAC__int32 *const ibuffer[]
, void *obuffer)
{
FLAC__uint64 i, ch;
unsigned channels = frame->header.channels;
(void)decoder;
switch (round_to_bytes(frame->header.bits_per_sample))
{
case 1:
/* If sample width is equal or less than 8 bit, we deal with one
* byte per sample and samples are unsigned as per WAVE spec. */
for (i = 0; i < frame->header.blocksize; i++)
{
for (ch = 0; ch < channels; ch++)
{
/* Shift back into unsigned values by adding 0x7f. */
*((FLAC__uint8 *)obuffer + i * channels + ch)
= (FLAC__uint8)ibuffer[ch][i] + 0x80;
}
}
break;
case 2:
/* Here we have signed samples, each having width equal to 16
* bits. */
for (i = 0; i < frame->header.blocksize; i++)
{
for (ch = 0; ch < channels; ch++)
{
*((FLAC__int16 *)obuffer + i * channels + ch)
= (FLAC__int16)ibuffer[ch][i];
}
}
break;
case 3:
/* Singed 24 bit samples. Going with 3 bytes step is not so
* handy. */
for (i = 0; i < frame->header.blocksize; i++)
{
for (ch = 0; ch < channels; ch++)
{
*(FLAC__int32 *)((FLAC__byte *)obuffer + (i * channels + ch) * 3)
= (FLAC__int32)ibuffer[ch][i];
}
}
break;
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
static void error_callback
( const FLAC__StreamDecoder *decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data )
{
(void)decoder, (void)status, (void)client_data;
return;
}
FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_helper
( FLAC__StreamDecoder *decoder
, char *ifile_name
, void *buffer )
{
return FLAC__stream_decoder_init_file
(decoder, ifile_name, write_callback, NULL, error_callback, buffer);
}