iOS 画平滑曲线的步骤及取音频数据的方法
iOS 画平滑曲线的方法及取音频数据的方法
ViewController.m
HLSonogramView.h
HLSonogramView.m
取音频数据和画波形图的方法
ViewController.h
// // 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
// // 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
// // 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 char *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
// // 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 = 1 * 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 char *fname, struct ret_value *ret) { NSLog(@"%s: %d", __func__, __LINE__); FILE *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 char *)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
本文代码例子:http://pan.baidu.com/s/1xKgIX