Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
audiowmark
Project
Project
Details
Activity
Releases
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
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
audiowmark
Commits
7b74c2cc
Commit
7b74c2cc
authored
Dec 02, 2019
by
Stefan Westerfeld
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support big endian / little endian format.
Signed-off-by:
Stefan Westerfeld
<
stefan@space.twc.de
>
parent
b19ef4a2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
108 additions
and
31 deletions
+108
-31
audiowmark.cc
src/audiowmark.cc
+27
-0
rawconverter.cc
src/rawconverter.cc
+63
-28
rawinputstream.cc
src/rawinputstream.cc
+6
-0
rawinputstream.hh
src/rawinputstream.hh
+12
-3
No files found.
src/audiowmark.cc
View file @
7b74c2cc
...
...
@@ -149,6 +149,17 @@ parse_format (const string& str)
exit
(
1
);
}
RawFormat
::
Endian
parse_endian
(
const
string
&
str
)
{
if
(
str
==
"little"
)
return
RawFormat
::
Endian
::
LITTLE
;
if
(
str
==
"big"
)
return
RawFormat
::
Endian
::
BIG
;
error
(
"audiowmark: unsupported endianness '%s'
\n
"
,
str
.
c_str
());
exit
(
1
);
}
void
parse_options
(
int
*
argc_p
,
char
**
argv_p
[])
...
...
@@ -241,6 +252,22 @@ parse_options (int *argc_p,
Params
::
raw_input_format
.
set_bit_depth
(
b
);
Params
::
raw_output_format
.
set_bit_depth
(
b
);
}
else
if
(
check_arg
(
argc
,
argv
,
&
i
,
"--raw-input-endian"
,
&
opt_arg
))
{
auto
e
=
parse_endian
(
opt_arg
);
Params
::
raw_input_format
.
set_endian
(
e
);
}
else
if
(
check_arg
(
argc
,
argv
,
&
i
,
"--raw-output-endian"
,
&
opt_arg
))
{
auto
e
=
parse_endian
(
opt_arg
);
Params
::
raw_output_format
.
set_endian
(
e
);
}
else
if
(
check_arg
(
argc
,
argv
,
&
i
,
"--raw-endian"
,
&
opt_arg
))
{
auto
e
=
parse_endian
(
opt_arg
);
Params
::
raw_input_format
.
set_endian
(
e
);
Params
::
raw_output_format
.
set_endian
(
e
);
}
else
if
(
check_arg
(
argc
,
argv
,
&
i
,
"--raw-channels"
,
&
opt_arg
))
{
int
c
=
atoi
(
opt_arg
);
...
...
src/rawconverter.cc
View file @
7b74c2cc
...
...
@@ -4,7 +4,7 @@
using
std
::
vector
;
template
<
int
BIT_DEPTH
>
template
<
int
BIT_DEPTH
,
RawFormat
::
Endian
ENDIAN
>
class
RawConverterImpl
:
public
RawConverter
{
public
:
...
...
@@ -12,24 +12,62 @@ public:
void
from_raw
(
const
std
::
vector
<
unsigned
char
>&
bytes
,
std
::
vector
<
float
>&
samples
);
};
template
<
int
BIT_DEPTH
>
static
RawConverter
*
create_with_bits
(
const
RawFormat
&
raw_format
,
Error
&
error
)
{
switch
(
raw_format
.
endian
())
{
case
RawFormat
:
:
LITTLE
:
return
new
RawConverterImpl
<
BIT_DEPTH
,
RawFormat
::
LITTLE
>
();
case
RawFormat
:
:
BIG
:
return
new
RawConverterImpl
<
BIT_DEPTH
,
RawFormat
::
BIG
>
();
}
error
=
Error
(
"unsupported endianness"
);
return
nullptr
;
}
RawConverter
*
RawConverter
::
create
(
const
RawFormat
&
raw_format
,
Error
&
error
)
{
error
=
Error
::
Code
::
NONE
;
switch
(
raw_format
.
bit_depth
())
{
case
16
:
return
new
RawConverterImpl
<
16
>
(
);
case
24
:
return
new
RawConverterImpl
<
24
>
(
);
case
16
:
return
create_with_bits
<
16
>
(
raw_format
,
error
);
case
24
:
return
create_with_bits
<
24
>
(
raw_format
,
error
);
default
:
error
=
Error
(
"unsupported bit depth"
);
return
nullptr
;
}
}
template
<
int
BIT_DEPTH
>
template
<
int
BIT_DEPTH
,
RawFormat
::
Endian
ENDIAN
>
constexpr
std
::
array
<
int
,
3
>
make_endian_shift
()
{
if
(
BIT_DEPTH
==
16
)
{
if
(
ENDIAN
==
RawFormat
::
Endian
::
LITTLE
)
return
{
16
,
24
,
-
1
};
else
return
{
24
,
16
,
-
1
};
}
if
(
BIT_DEPTH
==
24
)
{
if
(
ENDIAN
==
RawFormat
::
Endian
::
LITTLE
)
return
{
8
,
16
,
24
};
else
return
{
24
,
16
,
8
};
}
}
template
<
int
BIT_DEPTH
,
RawFormat
::
Endian
ENDIAN
>
void
RawConverterImpl
<
BIT_DEPTH
>::
to_raw
(
const
vector
<
float
>&
samples
,
vector
<
unsigned
char
>&
output_bytes
)
RawConverterImpl
<
BIT_DEPTH
,
ENDIAN
>::
to_raw
(
const
vector
<
float
>&
samples
,
vector
<
unsigned
char
>&
output_bytes
)
{
output_bytes
.
resize
(
BIT_DEPTH
/
8
*
samples
.
size
());
constexpr
int
sample_width
=
BIT_DEPTH
/
8
;
constexpr
auto
eshift
=
make_endian_shift
<
BIT_DEPTH
,
ENDIAN
>
();
output_bytes
.
resize
(
sample_width
*
samples
.
size
());
unsigned
char
*
ptr
=
output_bytes
.
data
();
for
(
size_t
i
=
0
;
i
<
samples
.
size
();
i
++
)
{
...
...
@@ -39,40 +77,37 @@ RawConverterImpl<BIT_DEPTH>::to_raw (const vector<float>& samples, vector<unsign
const
int
sample
=
lrint
(
bound
<
double
>
(
min_value
,
samples
[
i
]
*
norm
,
max_value
));
if
(
BIT_DEPTH
==
16
)
{
// write 16-bit little endian value
output_bytes
[
i
*
2
]
=
sample
>>
16
;
output_bytes
[
i
*
2
+
1
]
=
sample
>>
24
;
}
else
if
(
BIT_DEPTH
==
24
)
{
// write 24-bit little endian value
output_bytes
[
i
*
3
]
=
sample
>>
8
;
output_bytes
[
i
*
3
+
1
]
=
sample
>>
16
;
output_bytes
[
i
*
3
+
2
]
=
sample
>>
24
;
}
if
(
eshift
[
0
]
>=
0
)
ptr
[
0
]
=
sample
>>
eshift
[
0
];
if
(
eshift
[
1
]
>=
0
)
ptr
[
1
]
=
sample
>>
eshift
[
1
];
if
(
eshift
[
2
]
>=
0
)
ptr
[
2
]
=
sample
>>
eshift
[
2
];
ptr
+=
sample_width
;
}
}
template
<
int
BIT_DEPTH
>
template
<
int
BIT_DEPTH
,
RawFormat
::
Endian
ENDIAN
>
void
RawConverterImpl
<
BIT_DEPTH
>::
from_raw
(
const
vector
<
unsigned
char
>&
input_bytes
,
vector
<
float
>&
samples
)
RawConverterImpl
<
BIT_DEPTH
,
ENDIAN
>::
from_raw
(
const
vector
<
unsigned
char
>&
input_bytes
,
vector
<
float
>&
samples
)
{
const
unsigned
char
*
ptr
=
input_bytes
.
data
();
const
int
sample_width
=
BIT_DEPTH
/
8
;
constexpr
int
sample_width
=
BIT_DEPTH
/
8
;
constexpr
auto
eshift
=
make_endian_shift
<
BIT_DEPTH
,
ENDIAN
>
();
samples
.
resize
(
input_bytes
.
size
()
/
sample_width
);
const
double
norm
=
1.0
/
0x80000000LL
;
for
(
size_t
i
=
0
;
i
<
samples
.
size
();
i
++
)
{
int
s32
;
if
(
BIT_DEPTH
==
16
)
s32
=
(
ptr
[
1
]
<<
24
)
+
(
ptr
[
0
]
<<
16
);
int
s32
=
0
;
if
(
BIT_DEPTH
==
24
)
s32
=
(
ptr
[
2
]
<<
24
)
+
(
ptr
[
1
]
<<
16
)
+
(
ptr
[
0
]
<<
8
);
if
(
eshift
[
0
]
>=
0
)
s32
+=
ptr
[
0
]
<<
eshift
[
0
];
if
(
eshift
[
1
]
>=
0
)
s32
+=
ptr
[
1
]
<<
eshift
[
1
];
if
(
eshift
[
2
]
>=
0
)
s32
+=
ptr
[
2
]
<<
eshift
[
2
];
samples
[
i
]
=
s32
*
norm
;
ptr
+=
sample_width
;
...
...
src/rawinputstream.cc
View file @
7b74c2cc
...
...
@@ -36,6 +36,12 @@ RawFormat::set_bit_depth (int bits)
m_bit_depth
=
bits
;
}
void
RawFormat
::
set_endian
(
Endian
endian
)
{
m_endian
=
endian
;
}
RawInputStream
::~
RawInputStream
()
{
close
();
...
...
src/rawinputstream.hh
View file @
7b74c2cc
...
...
@@ -10,9 +10,16 @@
class
RawFormat
{
int
m_n_channels
=
0
;
int
m_sample_rate
=
0
;
int
m_bit_depth
=
0
;
public
:
enum
Endian
{
LITTLE
,
BIG
};
private
:
int
m_n_channels
=
0
;
int
m_sample_rate
=
0
;
int
m_bit_depth
=
0
;
Endian
m_endian
=
LITTLE
;
public
:
RawFormat
();
RawFormat
(
int
n_channels
,
int
sample_rate
,
int
bit_depth
);
...
...
@@ -20,10 +27,12 @@ public:
int
n_channels
()
const
{
return
m_n_channels
;
}
int
sample_rate
()
const
{
return
m_sample_rate
;
}
int
bit_depth
()
const
{
return
m_bit_depth
;
}
Endian
endian
()
const
{
return
m_endian
;
}
void
set_channels
(
int
channels
);
void
set_sample_rate
(
int
rate
);
void
set_bit_depth
(
int
bits
);
void
set_endian
(
Endian
endian
);
};
class
RawConverter
;
...
...
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