0
在我的應用程序中,我試圖在一臺設備上錄製,傳輸並在其他設備上播放。我想在錄音設備和播放設備上設置動畫效果。無法同時錄製/播放AudioQueue和動畫
我用於錄製,回放和動畫的大部分代碼來自SpeakHere示例應用程序。
我雖然有兩個區別:
- 我已經通過網絡傳輸的額外開銷。
- 我一個試圖在SpeakHere做和圖像(如下所示)的水平動畫代替彩色帶的
我記錄和在單獨的調度隊列發送(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);
}
謝謝hotpaw2。今天我會試試這個。需要看看它是否會在性能上產生重大影響。 – dagnytaggart 2012-07-12 19:28:30
它實際上比drawrect更容易實現,並且似乎與AudioQueue一起正常工作,謝謝! – dagnytaggart 2012-07-13 05:15:25