Skip to content

Commit

Permalink
Removed option to remove hex prefix from ASCII
Browse files Browse the repository at this point in the history
ASCII LPC bitstreams without a hex prefix complicate the process
of parsing and importing bitstreams
  • Loading branch information
tornupnegatives committed Mar 29, 2024
1 parent 58f26fc commit 44707bb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/bitstream/BitstreamGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ std::string BitstreamGenerator::serializeFrames(
const std::string& name, const std::vector<Frame>& frame_table,
BitstreamParameters params) {
auto encoder =
FrameEncoder(frame_table, params.encoder_style != ENCODER_STYLE_ASCII);
FrameEncoder(frame_table);
std::string bitstream;

switch (params.encoder_style) {
Expand Down
24 changes: 6 additions & 18 deletions src/encoding/FrameEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,14 @@ namespace tms_express {
// Initializers ///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

FrameEncoder::FrameEncoder(bool include_hex_prefix) {
include_hex_prefix_ = include_hex_prefix;
FrameEncoder::FrameEncoder() {
frames_ = std::vector<Frame>();
binary_bitstream_ = std::vector<std::string>(1, "");
}

FrameEncoder::FrameEncoder(const std::vector<Frame> &frames,
bool include_hex_prefix) {
//
FrameEncoder::FrameEncoder(const std::vector<Frame> &frames) {
binary_bitstream_ = std::vector<std::string>(1, "");
frames_ = std::vector<Frame>();
include_hex_prefix_ = include_hex_prefix;

append(frames);
}
Expand Down Expand Up @@ -162,7 +158,7 @@ std::string FrameEncoder::toHex(bool shouldAppendStopFrame) {
// Reverse each byte and convert to hex
for (auto byte : binary_bitstream_) {
std::reverse(byte.begin(), byte.end());
hex_stream += binToHex(byte, include_hex_prefix_) + byte_delimiter;
hex_stream += binToHex(byte) + byte_delimiter;
}

// Remove final trailing comma
Expand All @@ -187,7 +183,7 @@ std::vector<std::byte> FrameEncoder::toBytes(bool append_stop_frame) {
for (auto byte : binary_bitstream_) {
std::reverse(byte.begin(), byte.end());
auto data = std::byte(
std::stoul(binToHex(byte, include_hex_prefix_), nullptr, 16));
std::stoul(binToHex(byte), nullptr, 16));
bytes.push_back(data);
}

Expand Down Expand Up @@ -216,20 +212,12 @@ std::vector<Frame> FrameEncoder::getFrameTable() const {
// Static Helpers /////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

std::string FrameEncoder::binToHex(const std::string &bin_str,
bool include_hex_prefix) {
//
std::string FrameEncoder::binToHex(const std::string &bin_str) {
// TODO(Joseph Bellahcen): Handle exception
int value = std::stoi(bin_str, nullptr, 2);

char hex_byte[6];

if (include_hex_prefix) {
snprintf(hex_byte, sizeof(hex_byte), "0x%02x", value);
} else {
snprintf(hex_byte, sizeof(hex_byte), "%02x", value);
}

snprintf(hex_byte, sizeof(hex_byte), "0x%02x", value);
return {hex_byte};
}

Expand Down
16 changes: 3 additions & 13 deletions src/encoding/FrameEncoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,11 @@ class FrameEncoder {
///////////////////////////////////////////////////////////////////////////

/// @brief Creates a new Frame Encoder with empty Frame buffer
/// @param include_hex_prefix true to include '0x' in front of hex bytes,
/// false otherwise
explicit FrameEncoder(bool include_hex_prefix = false);
FrameEncoder();

/// @brief Creates a new Frame Encoder, starting with given Frame buffer
/// @param frames Vector of Frames to encode
/// @param include_hex_prefix true to include '0x' in front of hex bytes,
/// false otherwise
explicit FrameEncoder(const std::vector<Frame> &frames,
bool include_hex_prefix = false);
explicit FrameEncoder(const std::vector<Frame> &frames);

///////////////////////////////////////////////////////////////////////////
// Frame Appenders ////////////////////////////////////////////////////////
Expand Down Expand Up @@ -90,10 +85,8 @@ class FrameEncoder {

/// @brief Converts binary string to ASCII hex byte
/// @param bin_str Binary string corresponding to byte
/// @param include_hex_prefix true to include '0x' prefix, false otherwise
/// @return ASCII hex representation of binary string
static std::string binToHex(const std::string &bin_str,
bool include_hex_prefix);
static std::string binToHex(const std::string &bin_str);

/// @brief Reverses hex bytes in bitstream, effectively converting between
/// host representation and TMS6100 Voice Synthesis Memory format
Expand Down Expand Up @@ -139,9 +132,6 @@ class FrameEncoder {

/// @brief Frame table
std::vector<Frame> frames_;

/// @brief true to prefix hex bytes with '0x', false otherwise
bool include_hex_prefix_;
};

}; // namespace tms_express
Expand Down
67 changes: 36 additions & 31 deletions test/FrameEncoderTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ TEST(FrameEncoderTests, StopFrame) {
auto frame_encoder = FrameEncoder();

auto hex = frame_encoder.toHex();
EXPECT_EQ(hex, "0f");
EXPECT_EQ(hex, "0x0f");
}

TEST(FrameEncoderTests, AsciiStopFrame) {
Expand All @@ -22,7 +22,7 @@ TEST(FrameEncoderTests, AsciiStopFrame) {
frame_encoder.importASCIIFromString("0x0f");

auto hex = frame_encoder.toHex();
EXPECT_EQ(hex, "0f");
EXPECT_EQ(hex, "0x0f");
}

TEST(FrameEncoderTests, SilentFrame) {
Expand All @@ -39,15 +39,15 @@ TEST(FrameEncoderTests, SilentFrame) {
frame_encoder.append(silent_frame);

auto hex = frame_encoder.toHex();
EXPECT_EQ(hex, "f0");
EXPECT_EQ(hex, "0xf0");
}

TEST(FrameEncoderTests, AsciiSilentFrame) {
auto frame_encoder = FrameEncoder();
frame_encoder.importASCIIFromString("0xf0");

auto hex = frame_encoder.toHex();
EXPECT_EQ(hex, "f0");
EXPECT_EQ(hex, "0xf0");
}

TEST(FrameEncoderTests, VoicedFrame) {
Expand All @@ -57,81 +57,86 @@ TEST(FrameEncoderTests, VoicedFrame) {
// reversed, as the TMS5100 Voice Synthesis Memory units which normally
// feed data into the TMS5220 send byte-wise data LSB first

auto voiced_frame = Frame(38, true, 56.850773,
{-0.753234, 0.939525, -0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028});
auto voiced_frame =
Frame(38, true, 56.850773,
{-0.753234, 0.939525, -0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028});

auto frame_encoder = FrameEncoder();
frame_encoder.append(voiced_frame);

auto bin = frame_encoder.toHex();
EXPECT_EQ(bin, "c8,88,4f,25,ce,ab,3c");
EXPECT_EQ(bin, "0xc8,0x88,0x4f,0x25,0xce,0xab,0x3c");
}

TEST(FrameEncoderTests, AsciiVoicedFrame) {
auto frame_encoder = FrameEncoder();
frame_encoder.importASCIIFromString("0xc8,0x88,0x4f,0x25,0xce,0xab,0x3c");

auto bin = frame_encoder.toHex();
EXPECT_EQ(bin, "c8,88,4f,25,ce,ab,3c");
EXPECT_EQ(bin, "0xc8,0x88,0x4f,0x25,0xce,0xab,0x3c");
}

TEST(FrameEncoderTests, UnvoicedFrame) {
// An unvoiced Frame will produce 29 data bits. The output will also
// contain 4 stop bits.

auto unvoiced_frame = Frame(38, false, 56.850773,
{-0.753234, 0.939525, -0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028});
auto unvoiced_frame =
Frame(38, false, 56.850773,
{-0.753234, 0.939525, -0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028});

auto frame_encoder = FrameEncoder();
frame_encoder.append(unvoiced_frame);

auto bin = frame_encoder.toHex();
EXPECT_EQ(bin, "08,88,4f,e5,01");
EXPECT_EQ(bin, "0x08,0x88,0x4f,0xe5,0x01");
}

TEST(FrameEncoderTests, AsciiUnvoicedFrame) {
auto frame_encoder = FrameEncoder();
frame_encoder.importASCIIFromString("0x08,0x88,0x4f,0xe5,0x01");

auto bin = frame_encoder.toHex();
EXPECT_EQ(bin, "08,88,4f,e5,01");
EXPECT_EQ(bin, "0x08,0x88,0x4f,0xe5,0x01");
}

TEST(FrameEncoderTests, MixtureOfFrames) {
auto frames = std::vector<Frame>(
{
Frame(0, false, 0, {-0.753234, 0.939525, -0.342255, -0.172317,
0.108887, 0.679660, 0.056874, 0.433271, -0.220355,
0.17028}),
{Frame(0, false, 0,
{-0.753234, 0.939525, -0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028}),

Frame(38, true, 142.06, {-0.653234, 0.139525, 0.342255, -0.172317,
0.108887, 0.679660, 0.056874, 0.433271, -0.220355,
0.17028}),
Frame(38, true, 142.06,
{-0.653234, 0.139525, 0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028}),

Frame(38, true, 142.06, {-0.653234, 0.139525, 0.342255, -0.172317,
0.108887, 0.679660, 0.056874, 0.433271, -0.220355,
0.17028}),
Frame(38, true, 142.06,
{-0.653234, 0.139525, 0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028}),

Frame(38, false, 56.850773, {-0.753234, 0.939525, -0.342255,
-0.172317, 0.108887, 0.679660, 0.056874, 0.433271,
-0.220355, 0.17028})
});
Frame(38, false, 56.850773,
{-0.753234, 0.939525, -0.342255, -0.172317, 0.108887, 0.679660,
0.056874, 0.433271, -0.220355, 0.17028})});

auto frame_encoder = FrameEncoder(frames);

auto bin = frame_encoder.toHex();
EXPECT_EQ(bin, "c0,8c,a4,5b,e2,bc,0a,33,92,6e,89,f3,2a,08,88,4f,e5,01");
EXPECT_EQ(bin,
"0xc0,0x8c,0xa4,0x5b,0xe2,0xbc,0x0a,0x33,0x92,0x6e,0x89,0xf3,"
"0x2a,0x08,0x88,0x4f,0xe5,0x01");
}

TEST(FrameEncoderTests, AsciiMixtureOfFrames) {
auto frame_encoder = FrameEncoder();
frame_encoder.importASCIIFromString("0xc0,0x8c,0xa4,0x5b,0xe2,0xbc,0x0a," \
frame_encoder.importASCIIFromString(
"0xc0,0x8c,0xa4,0x5b,0xe2,0xbc,0x0a,"
"0x33,0x92,0x6e,0x89,0xf3,0x2a,0x08,0x88,0x4f,0xe5,0x01");

auto bin = frame_encoder.toHex();
EXPECT_EQ(bin, "c0,8c,a4,5b,e2,bc,0a,33,92,6e,89,f3,2a,08,88,4f,e5,01");
EXPECT_EQ(bin,
"0xc0,0x8c,0xa4,0x5b,0xe2,0xbc,0x0a,0x33,0x92,0x6e,0x89,0xf3,"
"0x2a,0x08,0x88,0x4f,0xe5,0x01");
}

}; // namespace tms_express

0 comments on commit 44707bb

Please sign in to comment.