Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
e166ddf4
Commit
e166ddf4
authored
Oct 02, 2012
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pcm_channels: support floating point samples
parent
31e1be75
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
62 deletions
+105
-62
pcm_channels.c
src/pcm_channels.c
+71
-0
pcm_channels.h
src/pcm_channels.h
+17
-0
pcm_convert.c
src/pcm_convert.c
+17
-62
No files found.
src/pcm_channels.c
View file @
e166ddf4
...
...
@@ -244,3 +244,74 @@ pcm_convert_channels_32(struct pcm_buffer *buffer,
return
dest
;
}
static
void
pcm_convert_channels_float_1_to_2
(
float
*
dest
,
const
float
*
src
,
const
float
*
src_end
)
{
pcm_convert_channels_24_1_to_2
((
int32_t
*
)
dest
,
(
const
int32_t
*
)
src
,
(
const
int32_t
*
)
src_end
);
}
static
void
pcm_convert_channels_float_2_to_1
(
float
*
restrict
dest
,
const
float
*
restrict
src
,
const
float
*
restrict
src_end
)
{
while
(
src
<
src_end
)
{
double
a
=
*
src
++
,
b
=
*
src
++
;
*
dest
++
=
(
a
+
b
)
/
2
;
}
}
static
void
pcm_convert_channels_float_n_to_2
(
float
*
dest
,
unsigned
src_channels
,
const
float
*
src
,
const
float
*
src_end
)
{
unsigned
c
;
assert
(
src_channels
>
0
);
while
(
src
<
src_end
)
{
double
sum
=
0
;
float
value
;
for
(
c
=
0
;
c
<
src_channels
;
++
c
)
sum
+=
*
src
++
;
value
=
sum
/
(
double
)
src_channels
;
/* XXX this is actually only mono ... */
*
dest
++
=
value
;
*
dest
++
=
value
;
}
}
const
float
*
pcm_convert_channels_float
(
struct
pcm_buffer
*
buffer
,
unsigned
dest_channels
,
unsigned
src_channels
,
const
float
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
)
{
assert
(
src_size
%
(
sizeof
(
*
src
)
*
src_channels
)
==
0
);
size_t
dest_size
=
src_size
/
src_channels
*
dest_channels
;
*
dest_size_r
=
dest_size
;
float
*
dest
=
pcm_buffer_get
(
buffer
,
dest_size
);
const
float
*
src_end
=
pcm_end_pointer
(
src
,
src_size
);
if
(
src_channels
==
1
&&
dest_channels
==
2
)
pcm_convert_channels_float_1_to_2
(
dest
,
src
,
src_end
);
else
if
(
src_channels
==
2
&&
dest_channels
==
1
)
pcm_convert_channels_float_2_to_1
(
dest
,
src
,
src_end
);
else
if
(
dest_channels
==
2
)
pcm_convert_channels_float_n_to_2
(
dest
,
src_channels
,
src
,
src_end
);
else
return
NULL
;
return
dest
;
}
src/pcm_channels.h
View file @
e166ddf4
...
...
@@ -77,4 +77,21 @@ pcm_convert_channels_32(struct pcm_buffer *buffer,
unsigned
src_channels
,
const
int32_t
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
);
/**
* Changes the number of channels in 32 bit float PCM data.
*
* @param buffer the destination pcm_buffer object
* @param dest_channels the number of channels requested
* @param src_channels the number of channels in the source buffer
* @param src the source PCM buffer
* @param src_size the number of bytes in #src
* @param dest_size_r returns the number of bytes of the destination buffer
* @return the destination buffer
*/
const
float
*
pcm_convert_channels_float
(
struct
pcm_buffer
*
buffer
,
unsigned
dest_channels
,
unsigned
src_channels
,
const
float
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
);
#endif
src/pcm_convert.c
View file @
e166ddf4
...
...
@@ -61,55 +61,6 @@ pcm_convert_reset(struct pcm_convert_state *state)
pcm_resample_reset
(
&
state
->
resample
);
}
static
const
void
*
pcm_convert_channels
(
struct
pcm_buffer
*
buffer
,
enum
sample_format
format
,
uint8_t
dest_channels
,
uint8_t
src_channels
,
const
void
*
src
,
size_t
src_size
,
size_t
*
dest_size_r
,
GError
**
error_r
)
{
const
void
*
dest
=
NULL
;
switch
(
format
)
{
case
SAMPLE_FORMAT_UNDEFINED
:
case
SAMPLE_FORMAT_S8
:
case
SAMPLE_FORMAT_FLOAT
:
case
SAMPLE_FORMAT_DSD
:
g_set_error
(
error_r
,
pcm_convert_quark
(),
0
,
"Channel conversion not implemented for format '%s'"
,
sample_format_to_string
(
format
));
return
NULL
;
case
SAMPLE_FORMAT_S16
:
dest
=
pcm_convert_channels_16
(
buffer
,
dest_channels
,
src_channels
,
src
,
src_size
,
dest_size_r
);
break
;
case
SAMPLE_FORMAT_S24_P32
:
dest
=
pcm_convert_channels_24
(
buffer
,
dest_channels
,
src_channels
,
src
,
src_size
,
dest_size_r
);
break
;
case
SAMPLE_FORMAT_S32
:
dest
=
pcm_convert_channels_32
(
buffer
,
dest_channels
,
src_channels
,
src
,
src_size
,
dest_size_r
);
break
;
}
if
(
dest
==
NULL
)
{
g_set_error
(
error_r
,
pcm_convert_quark
(),
0
,
"Conversion from %u to %u channels "
"is not implemented"
,
src_channels
,
dest_channels
);
return
NULL
;
}
return
dest
;
}
static
const
int16_t
*
pcm_convert_16
(
struct
pcm_convert_state
*
state
,
const
struct
audio_format
*
src_format
,
...
...
@@ -273,19 +224,6 @@ pcm_convert_float(struct pcm_convert_state *state,
assert
(
dest_format
->
format
==
SAMPLE_FORMAT_FLOAT
);
/* convert channels first, hoping the source format is
supported (float is not) */
if
(
dest_format
->
channels
!=
src_format
->
channels
)
{
buffer
=
pcm_convert_channels
(
&
state
->
channels_buffer
,
src_format
->
format
,
dest_format
->
channels
,
src_format
->
channels
,
buffer
,
size
,
&
size
,
error_r
);
if
(
buffer
==
NULL
)
return
NULL
;
}
/* convert to float now */
buffer
=
pcm_convert_to_float
(
&
state
->
format_buffer
,
...
...
@@ -298,6 +236,23 @@ pcm_convert_float(struct pcm_convert_state *state,
return
NULL
;
}
/* convert channels */
if
(
src_format
->
channels
!=
dest_format
->
channels
)
{
buffer
=
pcm_convert_channels_float
(
&
state
->
channels_buffer
,
dest_format
->
channels
,
src_format
->
channels
,
buffer
,
size
,
&
size
);
if
(
buffer
==
NULL
)
{
g_set_error
(
error_r
,
pcm_convert_quark
(),
0
,
"Conversion from %u to %u channels "
"is not implemented"
,
src_format
->
channels
,
dest_format
->
channels
);
return
NULL
;
}
}
/* resample with float, because this is the best format for
libsamplerate */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment