2011-04-05 8 views
2

아마도 C 개발자를위한 매우 쉬운 질문이지만, 저는 C를 처음 접했고 아직 모든 개념을 완전히 이해하지 못했습니다. 더 나은 방법이 있어야한다는이 잘 작동C에서 버퍼 (부호없는 char *) 연결

typedef struct { 
    unsigned char * data; 
    UInt32 size;  
} SoundData; 

    SoundData audioData; 
      audioData.data = audioFiles[currentSoundDataIndex]; 
      audioData.size = audioFilesSize[currentSoundDataIndex]; 

    SoundData silenceData; 
       silenceData.size = 44100*2*fabs(silenceDuration-0.049f); 
       silenceData.data = malloc(silenceData.size);   
       memset(silenceData.data,0,silenceData.size); 

       //beat data 
    SoundData beatData; 
       beatData.size = (audioData.size + silenceData.size);  
       beatData.data = malloc(beatData.size); 

       for (int i=0; i<audioData.size; i++) { 
        beatData.data[i] = audioData.data[i]; 
       } 

       for (int i=audioData.size; i<beatData.size; i++) { 
        beatData.data[i] = silenceData.data[i-audioData.size]; 
       } 

,하지만 난 느낌이 : 그래서 지금, 나는 일부 오디오를 스트리밍 2 버퍼 (audioData 및 silenceData)를 연결하여 다음을 사용하려면이 코드를 사용 그것을 할 수있는, 어쩌면 일부 기능을 내장? 한 번 들어

+0

를 잘'memcpy' 아마 유용 할 것이다. – Erik

+0

이상하게도, 나는 그것을 시도했기 때문에 작동하지 못했습니다 (사운드가 완전히 변경되었습니다!), 아마도 제대로 사용되지 않았지만, 꽤 똑바로 있지만, 다시 시도 할 것입니다 ... –

+0

왜 C++ 태그입니까? C++ 솔루션은 다소 다릅니다. – Cubbi

답변

2
확실히 memcpy() ... 그 표준 라이브러리 기능이 크게 다른 버퍼에 바이트 하나의 버퍼의 복사 속도를 위해 컴파일러 내장 함수 또는 손으로 코딩 어셈블리를 사용하기 때문에 훨씬 더 빨리 될 것 사용하는 것이

프로세서 플랫폼에 맞게 최적화 할 수 있습니다. 즉 ... A의 루프보다 훨씬 빠르다 그래서 예를 들면

:

unsigned char* temp_buffer_loc = beatData.data; 
memcpy(temp_buffer_loc, audioData.data, audioData.size); 

//now put silence data at the end of the buffer 
temp_buffer_loc += audioData.size; 
memset(temp_buffer_loc, 0, silenceData.size); 
+0

이것은 매력적 이었지만 (위의 솔루션 중 하나라도 가능할 것이라고는 생각했지만), 나는 그것을 좋아한다. 왜냐하면 코드를 만드는 무음 버퍼를 mallocing하는 대신 알려진 바이트 수에서 memset을 사용하기 때문이다. 더 잘 보이고 (코드가 적음) 아마도 최적화 된 것일까?) –

+0

글쎄요, 주요 최적화는 이러한 표준 라이브러리 메모리 기능이 대개 두꺼운 작업을 위해 어셈블리를 사용한다는 사실입니다. for 루프 (루프 테스트를위한 코드 분기 포함)를위한 많은 어셈블리 코드 라인이 필요한 것은 원본 주소, 대상 주소, 복사 횟수를 설정하기 위해 약 3-4 개의 명령으로 신속하게 추출 할 수 있습니다 , 그리고/또는 버퍼를 채우기위한 것. 따라서 간단한 메모리 복사 기능의 경우 많은 수작업 코딩 루프가 느슨해집니다. 루프는 최적화 될 수 있지만 특정 명령만큼 빠르지는 않습니다. – Jason

+0

BTW, yes, allocate 할 필요가없고'silenceData.data'에서'beatData.data'로 0의 버퍼를 복사하면 CPU 사이클이 절약됩니다. – Jason

3

대신 루프를 사용하여, 당신은 그것은 memcpy와 그 for 루프를 대체하기 위해 나을 훨씬 빠릅니다 방어 적이기, 즉 :

memcpy(beatData.data, audioData.data, audioData.size); 
+1

나는'memmove()'를 사용할 것이다. 그것은 항상 작동합니다. 이 문맥에서는'memcpy()'를 사용하는 것이 안전하지만 항상 작동하지는 않기 때문에'memmove()'를 사용하는 것이 더 안전합니다. YMMV. –

+0

조언 해 주셔서 감사합니다. – MByD

+0

그래, 시도해 볼게. 전에 시도해 봤는데 소리가 바뀌 었어. 아마도 사용하지 않았을거야. 다시 시도하고 질문을 업데이트 할거야! –

2

를 사용할 수 있습니다. 그렇지 않으면 괜찮습니다.

memcpy(beatData.data, audioData.data, audioData.size); 
memcpy(beatData.data + audioData.size, silenceData.data, silenceData.size); 

사실, 작성중인 무음 데이터는 단지 제로입니다. 나중에 다른 버퍼에 추가하기 위해 실제로 저장해야합니다. 따라서 두 번째 memcpymemset으로 바꿔야합니다.

memcpy(beatData.data, audioData.data, audioData.size); 
memcpy(beatData.data + audioData.size, 0, beatData.size - audioData.size); 
관련 문제