0

在我的應用程序中,我試圖在一臺設備上錄製,傳輸並在其他設備上播放。我想在錄音設備和播放設備上設置動畫效果。無法同時錄製/播放AudioQueue和動畫

我用於錄製,回放和動畫的大部分代碼來自SpeakHere示例應用程序。

我雖然有兩個區別:

  • 我已經通過網絡傳輸的額外開銷。
  • 我一個試圖在SpeakHere做和圖像(如下所示)的水平動畫代替彩色帶的

Animation

我記錄和在單獨的調度隊列發送(GCD)接收和回放也是一樣。

  • 我的第一個問題是:當我介紹動畫時,接收和回放變得非常慢,而且AudioQueue變得沉默。
  • 我的下一個問題是爲LevelMeter視圖設置清晰的背景。如果我這樣做,那麼動畫是亂碼。不確定動畫是如何連接到背景顏色的。

下面是我的SpeakHere示例的drawRect版本(未經過過優雅修改)。 請就我可能犯的錯誤提出建議。

我的理解是,由於UIKit,我不能在這裏爲動畫使用另一個線程。如果沒有,請糾正我。

- (void)drawRect:(CGRect)rect 
{ 
     //(); 
    CGContextRef cxt = NULL; 
    cxt = UIGraphicsGetCurrentContext(); 

    CGColorSpaceRef cs = NULL; 
    cs = CGColorSpaceCreateDeviceRGB(); 

    CGRect bds; 


    if (_vertical) 
    { 
     CGContextTranslateCTM(cxt, 0., [self bounds].size.height); 
     CGContextScaleCTM(cxt, 1., -1.); 
     bds = [self bounds]; 
    } else { 
     CGContextTranslateCTM(cxt, 0., [self bounds].size.height); 
     CGContextRotateCTM(cxt, -M_PI_2); 
     bds = CGRectMake(0., 0., [self bounds].size.height, [self bounds].size.width); 
    } 

    CGContextSetFillColorSpace(cxt, cs); 
    CGContextSetStrokeColorSpace(cxt, cs); 

    if (_numLights == 0) 
    { 
     int i; 
     CGFloat currentTop = 0.; 

     if (_bgColor) 
     { 
      [_bgColor set]; 
      CGContextFillRect(cxt, bds); 
     } 

     for (i=0; i<_numColorThresholds; i++) 
     { 
      LevelMeterColorThreshold thisThresh = _colorThresholds[i]; 
      CGFloat val = MIN(thisThresh.maxValue, _level); 

      CGRect rect = CGRectMake(
            0, 
            (bds.size.height) * currentTop, 
            bds.size.width, 
            (bds.size.height) * (val - currentTop) 
            ); 

      [thisThresh.color set]; 
      CGContextFillRect(cxt, rect); 

      if (_level < thisThresh.maxValue) break; 

      currentTop = val; 
     } 

     if (_borderColor) 
     { 
      [_borderColor set]; 
      CGContextStrokeRect(cxt, CGRectInset(bds, .5, .5)); 
     } 

    } 
    else 
    { 
     int light_i; 
     CGFloat lightMinVal = 0.; 
     CGFloat insetAmount, lightVSpace; 
     lightVSpace = bds.size.height/(CGFloat)_numLights; 
     if (lightVSpace < 4.) insetAmount = 0.; 
     else if (lightVSpace < 8.) insetAmount = 0.5; 
     else insetAmount = 1.; 

     int peakLight = -1; 
     if (_peakLevel > 0.) 
     { 
      peakLight = _peakLevel * _numLights; 
      if (peakLight >= _numLights) peakLight = _numLights - 1; 
     } 

     for (light_i=0; light_i<_numLights; light_i++) 
      { 
       CGFloat lightMaxVal = (CGFloat)(light_i + 1)/(CGFloat)_numLights; 
       CGFloat lightIntensity; 
       CGRect lightRect; 
       UIColor *lightColor; 

       if (light_i == peakLight) 
       { 
        lightIntensity = 1.; 
       } 
       else 
       { 
        lightIntensity = (_level - lightMinVal)/(lightMaxVal - lightMinVal); 
        lightIntensity = LEVELMETER_CLAMP(0., lightIntensity, 1.); 
        if ((!_variableLightIntensity) && (lightIntensity > 0.)) lightIntensity = 1.; 
       } 

       lightColor = _colorThresholds[0].color; 
       int color_i; 
       for (color_i=0; color_i<(_numColorThresholds-1); color_i++) 
       { 
        LevelMeterColorThreshold thisThresh = _colorThresholds[color_i]; 
        LevelMeterColorThreshold nextThresh = _colorThresholds[color_i + 1]; 
        if (thisThresh.maxValue <= lightMaxVal) lightColor = nextThresh.color; 
       } 

       lightRect = CGRectMake(
             0., 
             bds.size.height * ((CGFloat)(light_i)/(CGFloat)_numLights), 
             bds.size.width, 
             bds.size.height * (1./(CGFloat)_numLights) 
             ); 
       lightRect = CGRectInset(lightRect, insetAmount, insetAmount); 

       if (_bgColor) 
       { 
        [_bgColor set]; 
        CGContextFillRect(cxt, lightRect); 
       } 

       UIImage* image = [UIImage imageNamed:@"Pearl.png"]; 
       CGImageRef imageRef = image.CGImage; 


       if (lightIntensity == 1.) 
       { 
        CGContextDrawImage(cxt, lightRect, imageRef); 

        [lightColor set]; 
        //CGContextFillRect(cxt, lightRect); 
       } else if (lightIntensity > 0.) { 
        CGColorRef clr = CGColorCreateCopyWithAlpha([lightColor CGColor], lightIntensity); 
        CGContextSetFillColorWithColor(cxt, clr); 
        //CGContextFillRect(cxt, lightRect); 
        CGContextDrawImage(cxt, lightRect, imageRef); 

        CGColorRelease(clr); 
       } 

       if (_borderColor) 
       { 
        [_borderColor set]; 
        CGContextStrokeRect(cxt, CGRectInset(lightRect, 0.5, 0.5)); 
       } 

       lightMinVal = lightMaxVal; 
      }  
    } 

    CGColorSpaceRelease(cs); 
} 

回答

1

您的繪圖可能太慢,這可能會干擾音頻隊列回調的實時響應要求。

但是,由於您主要繪製大量靜態圖像,因此您可能需要考慮在各自的圖像視圖中分別放置點。您可以通過隱藏和取消隱藏子視圖來控制顯示的點數,而不需要任何drawRect代碼。

+0

謝謝hotpaw2。今天我會試試這個。需要看看它是否會在性能上產生重大影響。 – dagnytaggart 2012-07-12 19:28:30

+0

它實際上比drawrect更容易實現,並且似乎與AudioQueue一起正常工作,謝謝! – dagnytaggart 2012-07-13 05:15:25