2010-11-27 4 views
0

내 질문에 약간의 어려움이 있습니다. 정확하게 경험하지 못했습니다. "Singer"라는 개체의 인스턴스를 선언하고 있습니다. 인스턴스는 "singer1"이라고합니다. "singer1"은 오디오 신호를 생성합니다.iPhone에서 라이브 업데이트 사운드에 대한 도움말

OSStatus playbackCallback(void *inRefCon, 
         AudioUnitRenderActionFlags *ioActionFlags, 
         const AudioTimeStamp *inTimeStamp, 
         UInt32 inBusNumber, 
         UInt32 inNumberFrames, 
         AudioBufferList *ioData) {  

//Singer *me = (Singer *)inRefCon; 

static int phase = 0; 

for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) { 

    int samples = ioData->mBuffers[i].mDataByteSize/sizeof(SInt16); 

    SInt16 values[samples]; 

    float waves; 
    float volume=.5; 

    for(int j = 0; j < samples; j++) { 


     waves = 0; 


     waves += sin(kWaveform * 600 * phase)*volume; 
     waves += sin(kWaveform * 400 * phase)*volume; 
     waves += sin(kWaveform * 200 * phase)*volume; 
     waves += sin(kWaveform * 100 * phase)*volume;    

     waves *= 32500/4; // <--------- make sure to divide by how many waves you're stacking 

     values[j] = (SInt16)waves; 
     values[j] += values[j]<<16; 

     phase++; 

    } 

    memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16)); 

} 

return noErr; 

}

이의

99 %가 코드를 차용, 그래서 난 단지 어떻게 작동하는지에 대한 기본적인 이해를 가지고있다 (I : 자, 다음은 오디오 신호의 특성을 결정하는 코드는 OSStatus 클래스 나 메소드 또는 이것에 대한 정보는 모르지만, 600, 400, 200, 100의 4 라인을 볼 수 있습니까? 그것들은 빈도를 결정합니다. 지금, 제가하고 싶은 것은 (현재)입니다. 내 자신의 변수를 거기에 바꿀 수있는 상수 대신 삽입하십시오.이 변수는 "fr1"이라고합니다. "fr1"헤더 파일에 선언되어 있지만 컴파일하려고하면 " fr1 "을 신고하지 않았습니다. 현재이 문제를 해결할 수있는 방법은 다음과 같습니다. right be 내가 물건을 # import를 어디에 코드를 컴파일하고 나는 그것을 말한다면 singer1.fr1 실제로 값을 변경 것 같은 일 Neath, 나는, 라인

fr1=0.0;//any number will work properly 

에게 작품의 이런 종류를 추가합니다. 문제는 이제 이것입니다 : A)이 컴파일하고 지정된 톤이 재생됩니다 (0.0 톤 없음) 경고 "데이터 정의에 형식 또는 저장소 클래스가 없습니다"및 "형식 기본값은 'int'선언에 'fr1' ". 어떤 이유로이 헤더 파일에서 내 이전 선언을 볼 수 없기 때문입니다. 그러나이 줄을 나가면 "fr1이 선언되지 않았기 때문에"코드가 컴파일되지 않습니다. B) fr1의 값을 변경한다고해서 singer1이 "playbackcallback"변수에 저장된 값을 업데이트하거나 출력 버퍼를 업데이트하는 것이 무엇이든 업데이트하는 것은 아닙니다. 아마도 이것은 다르게 코딩하여 수정할 수 있습니까? C)이 기능이 작동하더라도 오디오를 일시 중지/재생할 때 눈에 띄는 "갭"이 있습니다. 이것은 코드의 완전한 분해를 의미 할 수 있습니다. 따라서 어떤 것도 방해하지 않고 새로운 값을 "동적으로"삽입 할 수 있습니다. 그러나 게시하려는 모든 노력을 기울이는 이유는이 방법이 내가 원하는 것 (수학적으로 값을 계산할 수 있고 곧 DAC로 간다. 즉, 앞으로 삼각형을 만들 때 사용할 수 있음을 의미하기 때문이다. , 사각형, 등 파도 쉽게). 당신의 쾌락을 위해 pastebin에 Singer.h와 .m을 업로드했습니다. 아마 도움이 될 것입니다. 죄송합니다. 여기에 전체 링크가 있으므로 2 개의 HTML 태그를 게시 할 수 없습니다. 은 (http://pastebin.com/ewhKW2Tk는) (http://pastebin.com/CNAT4gFv)

그래서, TL; DR은, 내가 정말로 원하는 모두는 현재 식/값을 정의 할 수 있습니다 4 개의 파도 중 하나를 선택하고 소리에 틈이없이 매우 자주 다시 정의합니다. 감사합니다. . (그리고 미안, 게시물이 혼란 스럽거나 트랙에서 벗어났다면 꽤 확신 할 수 있습니다.)

답변

1

제 생각에 버퍼를 다시 채워야 할 때마다 콜백 함수가 호출됩니다. fr1..fr4를 변경하면 파형이 변경되지만 버퍼가 업데이트 될 때만 변경됩니다. 변경을 위해 사운드를 멈추고 다시 시작할 필요는 없지만 fr 값을 변경하면 음색에 갑작스런 변화가 있음을 알 수 있습니다. 팀버에서 원활한 전환을 위해서는 시간이 지남에 따라 fr 값이 부드럽게 변경되어야합니다. 버퍼 크기를 조정하면 fr 값이 변할 때 소리가 얼마나 반응하는지 사용자가 직접 제어 할 수 있습니다.

fr이 정의되지 않은 문제는 콜백이 직선적 인 C 함수이기 때문입니다. fr 변수는 Singer 객체의 일부로 objective-c 인스턴스 변수로 선언됩니다. 기본적으로 액세스 할 수 없습니다.

이 프로젝트를 살펴보고 콜백 내에서 인스턴스 변수에 대한 액세스를 구현하는 방법을 확인하십시오.기본적으로 인스턴스에 대한 참조를 콜백 함수에 전달한 다음이를 통해 인스턴스 변수에 액세스합니다.

https://github.com/youpy/dowoscillator

주의 :

Sinewave *sineObject = inRefCon; 
float freq = sineObject.frequency * 2 * M_PI/samplingRate; 

과 : 실제로 일부가 아니기 때문에 또한

AURenderCallbackStruct input; 
input.inputProc = RenderCallback; 
input.inputProcRefCon = self; 

, 당신이 당신의 @implementation 블록 외부에서 콜백 함수를 이동할 수 있습니다 가수 개체의.

당신은 모두 여기에 행동에서 볼 수 있습니다 https://github.com/coryalder/SineWaver

+0

야 케니, 답변 주셔서 감사. 나는 그가하고있는 일을 이해하고 있다고 생각하며, 목표 C 변수를 C 코드가 액세스 할 수있는 포인터로 바꾸고 있는가? -> 연산자는 "."과 같습니다. 하지만 포인터를 위해, 맞지? 어쨌든, @defs()는 더 이상 작동하지 않습니다 ... Xcode는 "@defs가 새로운 abi에서 지원되지 않습니다"라고 말합니다. 대신 무엇을 할 수 있습니까? 또한 얼마나 자주 버퍼를 업데이트합니까? singer1.fr1의 값이 바뀌 었음을 확인 했음에도 불구하고 사운드 변경을 듣지 못했기 때문에 (문자열로 바꾸고 UILabel로 전달하여). 또한 콜백 함수를 어디로 이동해야합니까? 정말 고맙습니다! – wyager

+0

나는 더 정확한 것으로 편집했습니다 ... 전체 @defs 것은 객관적인 C 객체에서 c-struct를 만드는 것입니다 ... 최선의 방법은 아닙니다. 속성을 설정했다면 객관적인 c 점 표기법을 사용하여 값에 액세스 할 수 있습니다. 어쨌든, 내가 연기를 내뿜고있는 것이 아니라는 것을 확인하기 위해, 나는 이것을 모든 프로젝트에 적용하기위한 새로운 프로젝트에서 이것을 설정했다. 그것을 확인해보십시오 https://github.com/coryalder/SineWaver –

+0

기본 버퍼가 1024 바이트라고 생각합니다 .. 당신이 내 SineWaver 프로젝트에서 슬라이더를 빠르게 움직이면 파형이 갑자기 버퍼가 다시 바뀔 때마다 팝이 들릴 수 있습니다. - 채우기. –

관련 문제