2011-01-10 24 views
7

Tôi có một mảng dữ liệu PCM, nó có thể là 16 bit, 24 bit đóng gói, 32 bit, vv .. Nó có thể được ký kết, hoặc unsigned, và nó có thể là điểm nổi 32 hoặc 64 bit. Nó hiện được lưu trữ dưới dạng ma trận "void **", được lập chỉ mục theo kênh, sau đó theo khung. Mục đích là để cho phép thư viện của tôi thực hiện bất kỳ định dạng PCM nào và đệm nó, mà không yêu cầu thao tác dữ liệu để phù hợp với cấu trúc được chỉ định. Nếu bộ chuyển đổi A/D phát ra các mảng được đóng gói 24 bit của PCM xen kẽ, tôi cần chấp nhận nó một cách duyên dáng. Tôi cũng cần hỗ trợ 16 bit không xen kẽ, cũng như bất kỳ hoán vị nào của các định dạng trên.Void * mảng đúc để nổi, int32, int16, vv

Tôi biết độ sâu bit và thông tin khác trong thời gian chạy và tôi đang cố gắng mã hiệu quả trong khi không sao chép mã. Những gì tôi cần là một cách hiệu quả để đúc ma trận, đưa dữ liệu PCM vào ma trận, và sau đó kéo nó ra sau.

Tôi có thể truyền ma trận đến int32_t, hoặc int16_t đối với PCM 32 và 16 bit tương ứng, có lẽ tôi sẽ lưu trữ PCM 24 bit trong một int32_t cho 32 bit, 8 bit hệ thống byte.

Có ai có thể giới thiệu cách tốt để đưa dữ liệu vào mảng này và kéo nó ra sau không? Tôi muốn tránh các đoạn mã lớn trông giống như:

switch(mFormat) 
{ 
case 1: // unsigned 8 bit 
    for(int i = 0; i < mChannels; i++) 
    framesArray = (uint8_t*)pcm[i]; 
    break; 
case 2: // signed 8 bit 
    for(int i = 0; i < mChannels; i++) 
    framesArray = (int8_t*)pcm[i]; 
    break; 
case 3: // unsigned 16 bit 
... 

Hạn chế: Tôi đang làm việc trong C/C++, không có mẫu, không RTTI, không STL. Hãy suy nghĩ được nhúng. Mọi thứ trở nên phức tạp hơn khi tôi phải chuyển sang DSP với 16 bit byte.

Có ai có bất kỳ macro hữu ích nào mà họ có thể sẵn sàng chia sẻ không?

Cảm ơn,

-Griff

+4

Tôi đã có thể nghĩ rằng đây chính là mẫu vấn đề được cho là để giải quyết. Là "không có mẫu" điều một giới hạn của toolchain của bạn, một số hạn chế khác về dự án, hoặc chỉ là một sở thích cá nhân? –

+2

Bạn làm gì với dữ liệu? Nó không rõ ràng từ các câu hỏi mà bạn thực sự cần phải làm đúc ở tất cả nếu tất cả các bạn làm là đệm dữ liệu thô và tay nó sau này. – Kylotan

+2

@Anon, vì OP thậm chí không chấp nhận cú pháp sao chép được bảo vệ bởi nhánh có điều kiện, tôi có thể đoán được vấn đề kích thước thực thi đang tăng cờ đỏ trên các mẫu. (kể từ khi chức năng mẫu kết quả trong thực thi lớn hơn so với chuyển đổi ... trường hợp) – YeenFei

Trả lời

5

một này sẽ phù hợp typecodes để đúc các chức năng. Ý tưởng cơ bản là nó tạo ra một tập hợp các hàm chuyển đổi nhỏ cho mỗi loại, và một mảng các con trỏ hàm, và sau đó chỉ mục vào mảng đó dựa trên định dạng dữ liệu để tìm hàm chuyển đổi chính xác để gọi.

sử dụng: tập tin

int main() 
{ 
    void** pcm; 
    int currentChannel; 
    int currentFrame; 
    int mFormat; 

    //gets data casted to our type 
    STORETYPE translatedFrameData = GET_FRAMEDATA(pcm, currentChannel, currentFrame, mFormat); 

    return 0; 
} 

tiêu đề:

// this is a big type, we cast to this one 
#define STORETYPE int32_t 

// these functions get a single frame 
typedef STORETYPE (*getterFunction)(void**, int, int); 

// this macros make an array that maps format codes to cast functions 
#define BEGIN_RESERVE_FORMAT_CODES getterFunction __getter_array[] = { 
#define RESERVE_FORMAT_CODE(code) __get__##code##__, 
#define END_RESERVE_FORMAT_CODES }; 

// 
#define FORMAT_DEFINITION(code, format) STORETYPE __get__##code##__(void**pcm, int channel, int frame) \ 
{ return (STORETYPE) ((format**)pcm)[channel][frame]; } 

// get corresponding function 
#define GET_FRAMEDATA(pcm, channel, frame, format) __getter_array[format](pcm,channel,frame) 

//serious part, define needed types 
FORMAT_DEFINITION(0, uint8_t) 
FORMAT_DEFINITION(1, int8_t) 
FORMAT_DEFINITION(2, uint16_t) 
FORMAT_DEFINITION(3, int16_t) 

//actually this makes the array which binds types 
BEGIN_RESERVE_FORMAT_CODES 
    RESERVE_FORMAT_CODE(0) 
    RESERVE_FORMAT_CODE(1) 
    RESERVE_FORMAT_CODE(2) 
    RESERVE_FORMAT_CODE(3) 
END_RESERVE_FORMAT_CODES 

//WATCH OUT FOR SEQUENCE 

hy vọng giúp

+0

Có xa câu hỏi của bạn không? Là chức năng gọi hiệu quả đủ trên nền tảng của bạn? – ch0kee

+0

Thats ... Genius. Đã cho tôi một thời gian để hiểu đầy đủ những gì bạn đang làm ở đây, nhưng nó _LOOKS_ khi xem đầu tiên được chính xác những gì tôi cần. Với một chút không quan trọng, tôi thậm chí có thể sử dụng các hàm này để đưa dữ liệu vào ma trận pcm. Điều này thật tuyệt vời. Phần thú vị là điều này sẽ làm việc với các kiểu dấu chấm động, cũng như các kiểu int. Cảm ơn một TON! – Griffin

+0

Tôi đã chỉnh sửa điều này để thêm mô tả ngắn gọn về giải pháp ở trên cùng, vì (như ghi chú của Griffin) nó không dễ hiểu ngay từ mã. Hy vọng bạn không phiền - Tôi nghĩ đó là một câu trả lời tuyệt vời. –

Các vấn đề liên quan