iOS 画平滑曲线的方法及取音频数据的方法

时间:2023-01-28 20:42:33

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