void memcpy_by_channel_mask2(void *dst, uint32_t dst_mask,
        const void *src, uint32_t src_mask, size_t sample_size, size_t count)
{
    int8_t idxary[32];
    uint32_t src_channels = popcount(src_mask);
    uint32_t dst_channels =
            memcpy_by_index_array_initialization(idxary, 32, dst_mask, src_mask);

    memcpy_by_index_array(dst, dst_channels, src, src_channels, idxary, sample_size, count);
}
示例#2
0
size_t memcpy_by_index_array_initialization_from_channel_mask(int8_t *idxary, size_t arysize,
        audio_channel_mask_t dst_channel_mask, audio_channel_mask_t src_channel_mask)
{
    const audio_channel_representation_t src_representation =
            audio_channel_mask_get_representation(src_channel_mask);
    const audio_channel_representation_t dst_representation =
            audio_channel_mask_get_representation(dst_channel_mask);
    const uint32_t src_bits = audio_channel_mask_get_bits(src_channel_mask);
    const uint32_t dst_bits = audio_channel_mask_get_bits(dst_channel_mask);

    switch (src_representation) {
    case AUDIO_CHANNEL_REPRESENTATION_POSITION:
        switch (dst_representation) {
        case AUDIO_CHANNEL_REPRESENTATION_POSITION:
            return memcpy_by_index_array_initialization(idxary, arysize,
                    dst_bits, src_bits);
        case AUDIO_CHANNEL_REPRESENTATION_INDEX:
            return memcpy_by_index_array_initialization_dst_index(idxary, arysize,
                    dst_bits, src_bits);
        default:
            return 0;
        }
        break;
    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
        switch (dst_representation) {
        case AUDIO_CHANNEL_REPRESENTATION_POSITION:
            return memcpy_by_index_array_initialization_src_index(idxary, arysize,
                    dst_bits, src_bits);
        case AUDIO_CHANNEL_REPRESENTATION_INDEX:
            return memcpy_by_index_array_initialization(idxary, arysize,
                    dst_bits, src_bits);
        default:
            return 0;
        }
        break;
    default:
        return 0;
    }
}
void memcpy_by_channel_mask(void *dst, uint32_t dst_mask,
        const void *src, uint32_t src_mask, size_t sample_size, size_t count)
{
#if 0
    /* alternate way of handling memcpy_by_channel_mask by using the idxary */
    int8_t idxary[32];
    uint32_t src_channels = popcount(src_mask);
    uint32_t dst_channels =
            memcpy_by_index_array_initialization(idxary, 32, dst_mask, src_mask);

    memcpy_by_idxary(dst, dst_channels, src, src_channels, idxary, sample_size, count);
#else
    if (dst_mask == src_mask) {
        memcpy(dst, src, sample_size * popcount(dst_mask) * count);
        return;
    }
    switch (sample_size) {
    case 1: {
        uint8_t *udst = (uint8_t*)dst;
        const uint8_t *usrc = (const uint8_t*)src;

        copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, 0);
    } break;
    case 2: {
        uint16_t *udst = (uint16_t*)dst;
        const uint16_t *usrc = (const uint16_t*)src;

        copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, 0);
    } break;
    case 3: { /* could be slow.  use a struct to represent 3 bytes of data. */
        uint8x3_t *udst = (uint8x3_t*)dst;
        const uint8x3_t *usrc = (const uint8x3_t*)src;
        static const uint8x3_t zero; /* tricky - we use this to zero out a sample */

        copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, zero);
    } break;
    case 4: {
        uint32_t *udst = (uint32_t*)dst;
        const uint32_t *usrc = (const uint32_t*)src;

        copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, 0);
    } break;
    default:
        abort(); /* illegal value */
        break;
    }
#endif
}
// a modified version of the memcpy_by_channel_mask test
// but using 24 bit type and memcpy_by_index_array()
TEST(audio_utils_primitives, memcpy_by_index_array) {
    uint32_t dst_mask;
    uint32_t src_mask;
    typedef struct {uint8_t c[3];} __attribute__((__packed__)) uint8x3_t;
    uint8x3_t *u24ref = new uint8x3_t[65536];
    uint8x3_t *u24ary = new uint8x3_t[65536];
    uint16_t *u16ref = new uint16_t[65536];
    uint16_t *u16ary = new uint16_t[65536];

    EXPECT_EQ(sizeof(uint8x3_t), 3); // 3 bytes per struct

    // tests prepare_index_array_from_masks()
    EXPECT_EQ(memcpy_by_index_array_initialization(NULL, 0, 0x8d, 0x8c), 4);
    EXPECT_EQ(memcpy_by_index_array_initialization(NULL, 0, 0x8c, 0x8d), 3);

    for (size_t i = 0; i < 65536; ++i) {
        u16ref[i] = i;
    }
    memcpy_to_p24_from_i16((uint8_t*)u24ref, (int16_t*)u16ref, 65536);

    // Test when src mask is 0.  Everything copied is zero.
    src_mask = 0;
    dst_mask = 0x8d;
    memset(u24ary, 0x99, 65536 * sizeof(u24ary[0]));
    memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]),
            65536 / popcount(dst_mask));
    memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536);
    EXPECT_EQ(nonZeroMono16((int16_t*)u16ary, 65530), 0);

    // Test when dst_mask is 0.  Nothing should be copied.
    src_mask = 0;
    dst_mask = 0;
    memset(u24ary, 0, 65536 * sizeof(u24ary[0]));
    memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]),
            65536);
    memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536);
    EXPECT_EQ(nonZeroMono16((int16_t*)u16ary, 65530), 0);

    // Test when masks are the same.  One to one copy.
    src_mask = dst_mask = 0x8d;
    memset(u24ary, 0x99, 65536 * sizeof(u24ary[0]));
    memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 555);
    EXPECT_EQ(memcmp(u24ary, u24ref, 555 * sizeof(u24ref[0]) * popcount(dst_mask)), 0);

    // Test with a gap in source:
    // Input 3 samples, output 4 samples, one zero inserted.
    src_mask = 0x8c;
    dst_mask = 0x8d;
    memset(u24ary, 0x9, 65536 * sizeof(u24ary[0]));
    memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]),
            65536 / popcount(dst_mask));
    memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536);
    checkMonotoneOrZero(u16ary, 65536);
    EXPECT_EQ(nonZeroMono16((int16_t*)u16ary, 65536), 65536 * 3 / 4 - 1);

    // Test with a gap in destination:
    // Input 4 samples, output 3 samples, one deleted
    src_mask = 0x8d;
    dst_mask = 0x8c;
    memset(u24ary, 0x9, 65536 * sizeof(u24ary[0]));
    memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]),
            65536 / popcount(src_mask));
    memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536);
    checkMonotone(u16ary, 65536 * 3 / 4);

    delete[] u16ref;
    delete[] u16ary;
    delete[] u24ref;
    delete[] u24ary;
}