2011-01-10 3 views
7

16 비트, 24 비트 패킹, 32 비트 등의 PCM 데이터 배열이 있습니다. 부호가 있거나 부호가없는 경우가 있습니다. 32 또는 64 비트 부동 소수점이 될 수 있습니다. 그것은 현재 "void **"행렬로 저장되고, 채널에 의해, 그리고 프레임별로 색인화됩니다. 목표는 지정된 구조에 맞게 데이터를 조작 할 필요없이 내 라이브러리에서 모든 PCM 형식을 가져 와서 버퍼링하는 것입니다. A/D 변환기가 인터리브 PCM의 24 비트 묶음 배열을 울려 퍼지면이를 정상적으로 받아 들여야합니다. 또한 위의 형식의 모든 순열뿐만 아니라 16 비트 비 인터리브도 지원해야합니다.float, int32, int16 등의 void 형 배열 캐스팅

런타임시 비트 심도 및 기타 정보를 알고 코드를 복제하지 않으면 서 효율적으로 코드를 작성하려고합니다. 필요한 것은 행렬을 캐스팅하고 행렬에 PCM 데이터를 넣은 다음 나중에 꺼내는 효과적인 방법입니다.

매트릭스를 32 비트 및 16 비트 부호있는 PCM 각각에 대해 int32_t 또는 int16_t로 캐스트 할 수 있습니다. 32 비트, 8 비트 바이트 시스템의 경우 int32_t에 24 비트 PCM을 저장해야 할 것입니다.

누구든지 데이터를이 배열에 넣고 나중에 꺼낼 수있는 좋은 방법을 추천 할 수 있습니까?

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 
... 

제한 : 나는 같이 코드의 많은 부분을 피하기 위해 싶습니다 내가 C/C++, 아니 템플릿, 아니 RTTI, 아니 STL에서 일하고 있어요. Think the embedded. 이것을 16 비트 바이트의 DSP로 이식해야 할 때 까다로워진다.

누구나 공유 할 수있는 유용한 매크로가 있습니까? 이 하나의 기능을 주조로 타입 코드와 일치합니다

-Griff

+4

나는이 정확하게 문제 템플릿이 해결하기로했다라고 생각했을 수 있습니다. "템플릿 없음"은 툴체인의 제한 사항입니까, 프로젝트의 일부 제한 사항입니까, 아니면 개인적인 취향입니까? –

+2

데이터로 무엇을합니까? 당신이해야 할 일은 원시 데이터를 버퍼에 저장하고 나중에 그것을 버리면 실제로 캐스팅을 수행해야한다는 것은 분명하지 않습니다. – Kylotan

+2

@Anon, OP가 조건부 분기에 의해 보호되는 복제 된 구문을 허용하지 않는다고 가정하면, 실행 파일 크기 문제가 템플릿에서 빨간색 플래그를 발생시키는 것 같습니다. (템플릿 함수가 switch ... case보다 큰 실행 파일을 생성하기 때문에) – YeenFei

답변

5

감사합니다. 기본 개념은 각 유형에 대한 일련의 작은 변환 함수와 함수 포인터의 배열을 만든 다음 호출 할 올바른 변환 함수를 찾기 위해 데이터 형식을 기반으로 해당 배열에 색인을 지정한다는 것입니다.

사용 :

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; 
} 

헤더 파일 :

// 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 

희망

+0

질문과 거리가 멀었습니까? 플랫폼에서 함수 호출이 충분히 효율적입니까? – ch0kee

+0

그게 ... 천재. 당신이 여기서하고있는 일을 완전히 이해하기 위해 잠시 시간을 들였지만, 내가 바라는 바로 그 순간을 첫눈에 볼 수 있습니다. 약간의 조작으로이 함수를 사용하여 데이터를 pcm 행렬에 넣을 수도 있습니다. 이것은 절대적으로 놀라운 것입니다. 멋진 부분은 이것이 int 유형뿐만 아니라 부동 소수점 유형에서도 작동해야한다는 것입니다. 엄청 고마워! – Griffin

+0

필자는 (Griffin 노트 에서처럼) 코드에서 바로 이해하기가 쉽지 않기 때문에 상단에 솔루션의 간결한 설명을 추가하기 위해 이것을 편집했습니다. 희망을 품지 않았 으면 좋겠다 - 나는 그것이 훌륭한 대답이라고 생각한다. –