http://www.2cto.com/kf/201310/251575.html
ViewController.h
[plain]
//
// ViewController.h
// iOS心电图Demo
//
// Created by 杜甲 on 13-10-18.
// Copyright (c) 2013年 杜甲. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "HLSonogramView.h"
@interface ViewController : UIViewController
@property (strong, nonatomic) HLSonogramView* hlSonogramView;
@end
ViewController.m
[objc]
//
// ViewController.m
// iOS心电图Demo
//
// Created by 杜甲 on 13-10-18.
// Copyright (c) 2013年 杜甲. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.hlSonogramView = [[HLSonogramView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:self.hlSonogramView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
HLSonogramView.h
[objc]
//
// HLSonogramView.h
// iOS心电图Demo
//
// Created by 杜甲 on 13-10-18.
// Copyright (c) 2013年 杜甲. All rights reserved.
//
#import <UIKit/UIKit.h>
#define kMaxKeyPoints 1000
#define kHillSegmentWidth 10
struct ret_value
{
unsigned charchar *data;//注意这里是unsigned char
unsigned long int size;
};
@interface HLSonogramView : UIView
{
CGPoint m_pSonogramKeyPoint[kMaxKeyPoints];
}
@property (assign ,nonatomic) float m_pOffsetX;
@property (assign ,nonatomic) int m_pSonogramKeyPointNum;
//转换后的座标数据,用于绘制波形图
@property (nonatomic, strong) NSMutableArray *m_pointWavArray;
@end
HLSonogramView.m
[objc]
//
// HLSonogramView.m
// iOS心电图Demo
//
// Created by 杜甲 on 13-10-18.
// Copyright (c) 2013年 杜甲. All rights reserved.
//
#import "HLSonogramView.h"
#define ScreenHeight [[UIScreen mainScreen] bounds].size.height
#define ScreenWidth [[UIScreen mainScreen] bounds].size.width
@implementation HLSonogramView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor whiteColor];
[self generatePoint];
}
return self;
}
-(void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextSetLineWidth(context, 1.0);
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, ScreenHeight / 2);
for (int i = 1; i < kMaxKeyPoints; i++) {
CGPoint p0 = m_pSonogramKeyPoint[i - 1];
CGPoint p1 = m_pSonogramKeyPoint[i];
int hSegments = floorf((p1.x - p0.x) / kHillSegmentWidth);
float dx = (p1.x - p0.x) / hSegments;
float da = M_PI / hSegments;
float ymid = (p0.y + p1.y) / 2;
float ampl = (p0.y - p1.y) / 2;
CGPoint pt0,pt1;
pt0 = p0;
for (int j = 0; j < hSegments + 1; ++j) {
pt1.x = p0.x + j * dx;
pt1.y = ymid + ampl * cosf(da * j);
CGContextAddLineToPoint(context, pt0.x, pt0.y);
CGContextAddLineToPoint(context, pt1.x, pt1.y);
pt0 = pt1;
}
}
CGContextStrokePath(context);
}
-(void)generatePoint
{
float m_pWinHeight = ScreenHeight;
float m_pWinWidth = ScreenWidth;
float x = 0;
float y = m_pWinHeight / 2;
for (int i = 0; i < kMaxKeyPoints; ++i) {
m_pSonogramKeyPoint[i] = CGPointMake(x, y);
x += m_pWinWidth / 2;
y = rand() % (int)m_pWinHeight;
}
}
//取音频数据
- (void)transformDateOFWavFromFile
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"wav"];
struct ret_value ret;
load_wave_file([path UTF8String], &ret);
// printf("data.size = %lu\n", ret.size);
int d = ret.size / 2;
short int wave_data[d];
for(long i=0; i<d; i++)
{
short int w = (ret.data[i*2+1]<<8) | ret.data[i*2];
//printf("%d\n", w);
wave_data[i] = w;
}
int myLineSize = d;
//--添加成员变量-方便外部调用----
CGPoint myLines[myLineSize];
self.m_pointWavArray = [NSMutableArray arrayWithCapacity:8];
//for(int i=0;i<myLineSize;i++)
//{
// myLines[i]=CGPointMake(10+i, [self getRandomNumber:200 to:400]);
//}
// for (int i = 0; i < d; i++) {
// NSLog(@"wave_data[i] = %hd",wave_data[i]);
// }
for (int i = 0; i < d ; i++) {
float x = 11 * i;
float y = 47.75 + wave_data[i] / 1000;
if (y < 5) {
y = 5;
}
if (y > 92.5) {
y = 92.5;
}
myLines[i] = CGPointMake(x, y);
NSValue *pValue = [NSValue valueWithCGPoint:myLines[i]];
[self.m_pointWavArray addObject:pValue];
}
// for(int i=0;i<d;i++)
// {
// float x = 10.0 + i * 300.0 / d;
// float y = 85+ 200.0 * wave_data[i] / 12767.0 ;
// // printf("x=%f, y=%f\n", x, y);
// myLines[i] = CGPointMake(x, y);
//
// //---存放到波形图的点数组中----------------
// NSValue *pValue = [NSValue valueWithCGPoint:myLines[i]];
// [self.m_pointWavArray addObject:pValue];
// }
NSLog(@"%@",self.m_pointWavArray);
}
void load_wave_file(const charchar *fname, struct ret_value *ret)
{
NSLog(@"%s: %d", __func__, __LINE__);
FILEFILE *fp;
fp = fopen(fname, "rb");
if(fp)
{
char id[5];
unsigned long size;
short format_tag, channels, block_align, bits_per_sample;//16 bit data
unsigned long format_length, sample_rate, avg_bytes_sec, data_size;//32 bit data
fread(id, sizeof(char), 4, fp);
id[4]='\0';
if (!strcmp(id, "RIFF"))
{
fread(&size, sizeof(unsigned long), 1, fp);//read file size
fread(id, sizeof(char), 4, fp);//read wave
id[4]='\0';
if (!strcmp(id, "WAVE"))
{
fread(id, sizeof(char), 4, fp);//读取4字节"fmt"
fread(&format_length, sizeof(unsigned long), 1, fp);
fread(&format_tag, sizeof(short), 1, fp);//读取文件tag
fread(&channels, sizeof(short), 1, fp);//读取通道数目
fread(&sample_rate, sizeof(unsigned long), 1, fp);//读取采样率大小
fread(&avg_bytes_sec, sizeof(unsigned long), 1, fp);//读取每秒数据量
fread(&block_align, sizeof(short), 1, fp);//读取块对齐
fread(&bits_per_sample, sizeof(short), 1, fp);//读取每一样本大小
fread(id, sizeof(char), 4, fp);//读取data
fread(&data_size, sizeof(unsigned long), 1, fp);
ret->size = data_size;
ret->data = (unsigned charchar *)malloc(sizeof(char)*data_size);//申请内存空间
fread(ret->data, sizeof(char), data_size, fp);//读取数据
printf("bits_per_sample = %d\n", bits_per_sample);
printf("channels = %d\n", channels);
printf("sample_rate = %lu\n", sample_rate);
}else{
printf("Error: RIFF file but not a wave file\n");
}
}else{
printf("Error: not a RIFF file\n");
}
fclose(fp);
}
}
@end