一 框架搭建
- 添加一个毛玻璃效果
- (void)setupBlurGlass
{
// 1.创建UIToolbar
UIToolbar *toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleBlack;
[self.albumView addSubview:toolbar];
// 2.给UIToolbar添加约束
[toolbar mas_makeConstraints:^(MASConstraintMaker *make) {
/*
make.width.equalTo(self.albumView.mas_width);
make.height.equalTo(self.albumView.mas_height);
make.centerX.equalTo(self.albumView.mas_centerX);
make.centerY.equalTo(self.albumView.mas_centerY);
*/
make.edges.equalTo(self.albumView);
}];
}
- 设置状态栏字体为白色
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- 歌手图片绘制成圆形
// 颜色抽成一个宏
#define GGColor(r,g,b) ([UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0])
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// 设置歌手图片的圆角
self.iconView.layer.cornerRadius = self.iconView.bounds.size.width * 0.5;
self.iconView.layer.masksToBounds = YES;
self.iconView.layer.borderWidth = 8;
self.iconView.layer.borderColor = GGColor(40, 40, 40).CGColor;
}
二 播放音乐
- 抽取工具类MusicTool,管理所有歌曲
static NSArray *_musics;
static GGMusic *_playingMusic;
+ (void)initialize
{
// 使用MJExtension 框架
_musics = [GGMusic objectArrayWithFilename:@"Musics.plist"];
_playingMusic = _musics[0];
}
+ (NSArray *)musics
{
return _musics;
}
// 获取当前正在播放的歌曲
+ (GGMusic *)playingMusic
{
return _playingMusic;
}
// 设置正在播放的歌曲
+ (void)setPlayingMusic:(GGMusic *)playingMusic
{
_playingMusic = playingMusic;
}
- 用工具类播放音乐
#pragma mark - 开始播放歌曲
- (void)startPlayingMusic
{
// 1.取出当前播放的歌曲
GGMusic *playingMusic = [GGMusicTool playingMusic];
// 2.设置界面的基本展示
self.albumView.image = [UIImage imageNamed:playingMusic.icon];
self.iconView.image = [UIImage imageNamed:playingMusic.icon];
self.songLabel.text = playingMusic.name;
self.singerLabel.text = playingMusic.singer;
// 3.开始播放歌曲
AVAudioPlayer *player = [GGAudioTool playMusicWithMusicName:playingMusic.filename];
self.currentTimeLabel.text = [NSString stringWithTime:player.currentTime]; // 当前时间
self.totalTimeLabel.text = [NSString stringWithTime:player.duration]; // 总时间
self.player = player;
// 4.给iconView添加旋转动画
[self addIconViewAnimation];
// 5.添加定时器
[self startProgressTimer];
}
- 新建分类NSString+GGTimeToString,时间转换拼接为字符串
+ (NSString *)stringWithTime:(NSTimeInterval)time
{
NSInteger min = time / 60;
NSInteger second = (NSInteger)time % 60;
return [NSString stringWithFormat:@"%02ld:%02ld", min, second];
}
三 旋转动画和进度完善
- 给iconView添加旋转动画
- (void)addIconViewAnimation
{
// 1.创建动画(基本动画)
CABasicAnimation *rotationAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
// 2.设置动画的属性
rotationAnim.fromValue = @(0);
rotationAnim.toValue = @(M_PI * 2);
rotationAnim.duration = 40.0;
rotationAnim.repeatCount = NSIntegerMax;
// 3.添加到iconView的layer
[self.iconView.layer addAnimation:rotationAnim forKey:nil];
}
- 更新进度条,搞一个定时器
#pragma mark - 对定时器的操作
- (void)startProgressTimer
{
[self updateProgress]; // 主动调用,防止1s间隔
self.progressTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateProgress) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.progressTimer forMode:NSRunLoopCommonModes];
}
- (void)stopProgressTimer
{
[self.progressTimer invalidate];
self.progressTimer = nil;
}
- (void)updateProgress
{
// 改变滑块的位置
self.slider.value = self.player.currentTime / self.player.duration;
// 设置当前播放时间的Label的文字
self.currentTimeLabel.text = [NSString stringWithTime:self.player.currentTime];
}
四 进度条事件处理
滑动进度条需要以下几个操作步骤:
- 1.移除定时器
- 2.滑动过程中改变当前播放时间
- 3.用户松手时播放当前时间对应音乐
定时器移除代码
- (void)stopProgressTimer
{
[self.progressTimer invalidate];
self.progressTimer = nil;
}
- 根据滑动位置比例计算出当前时间
#pragma mark 滑块的值改变
- (IBAction)sliderValueChange:(UISlider *)sender {
// 1.进度条当前进度的比例
CGFloat ratio = sender.value;
// 2.根据当前的比例,计算当前的时间
NSTimeInterval currentTime = self.player.duration * ratio;
// 3.改变currentTimeLabel的显示的文字
self.currentTimeLabel.text = [NSString stringWithTime:currentTime];
}
- 用户松手时播放当前位置对应时间的音乐
- 注意:进度条想要监听点击需要添加一个手势
#pragma mark 用户结束点击
- (IBAction)sliderTouchUpInside:(UISlider *)sender {
// 1.改变歌曲播放的进度
// 1.1.进度条当前进度的比例
CGFloat ratio = sender.value;
// 1.2.根据当前的比例,计算当前的时间
NSTimeInterval currentTime = self.player.duration * ratio;
// 1.3.改变歌曲播放的时间
self.player.currentTime = currentTime;
// 2.添加定时器
[self startProgressTimer];
}
- 进度条的点击
#pragma mark 进度条的点击
- (IBAction)sliderClick:(UITapGestureRecognizer *)sender {
// 1.获取进度条的比例
// 1.1.获取用户点击的位置
CGPoint point = [sender locationInView:sender.view];
// 1.2.计算比例
CGFloat ratio = point.x / self.slider.bounds.size.width;
// 2.计算当前应该播放的时间
NSTimeInterval currentTime = ratio * self.player.duration;
// 3.改变歌曲播放的进度
self.player.currentTime = currentTime;
// 4.更新进度(定时器会有1s 间隔)
[self updateProgress];
}
五 对歌曲控制的事件
- 上一首
- 抽取工具类方法
+ (GGMusic *)previousMusic
{
// 1.取出当前歌曲的下标值
NSUInteger currentIndex = [_musics indexOfObject:_playingMusic];
// 2.计算上一个歌曲的下表
NSInteger previousIndex = currentIndex - 1;
if (previousIndex < 0) {
previousIndex = _musics.count - 1;
}
// 3.取出上一个歌曲
return [_musics objectAtIndex:previousIndex];
}
- (IBAction)previousMusic {
// 0.取出当前歌曲
GGMusic *playingMusic = [GGGMusicTool playingMusic];
// 1.停止当前歌曲
[GGAudioTool stopMusicWithMusicName:playingMusic.filename];
// 2.取出下一首歌曲,并且播放
GGMusic *previousMusic = [GGMusicTool previousMusic];
[GGAudioTool playMusicWithMusicName:previousMusic.filename];
// 3.设置上一首歌曲成为当前播放的歌曲
[GGMusicTool setPlayingMusic:previousMusic];
// 4.改变界面信息成为上一首歌曲的信息
[self startPlayingMusic];
}
- 下一首
+ (GGMusic *)nextMusic
{
// 1.取出当前歌曲的下标值
NSUInteger currentIndex = [_musics indexOfObject:_playingMusic];
// 2.计算下一个歌曲的下表
NSInteger nextIndex = currentIndex + 1;
if (nextIndex > _musics.count - 1) {
nextIndex = 0;
}
// 3.取出上一个歌曲
return [_musics objectAtIndex:nextIndex];
}
- 上一首和下一首代码类似,抽成1个方法
- (void)switchMusicWithNextMusic:(BOOL)isNextMusic
{
// 0.取出当前歌曲
GGMusic *playingMusic = [GGMusicTool playingMusic];
// 1.停止当前歌曲
[GGAudioTool stopMusicWithMusicName:playingMusic.filename];
// 2.取出下一首歌曲,并且播放
GGMusic *changeMusic = nil;
if (isNextMusic) {
changeMusic = [GGMusicTool nextMusic];
} else {
changeMusic = [GGMusicTool previousMusic];
}
[GGAudioTool playMusicWithMusicName:changeMusic.filename];
// 3.设置上一首歌曲成为当前播放的歌曲
[GGMusicTool setPlayingMusic:changeMusic];
// 4.改变界面信息成为上一首歌曲的信息
[self startPlayingMusic];
}
- 暂停/播放
- 默认图片是选中状态
- (IBAction)playOrPauseMusic:(UIButton *)sender {
// 1.改变按钮的状态
sender.selected = !sender.isSelected;
// 2.根据歌曲是否在播放,来决定暂停还是播放
if (self.player.isPlaying) {
[self.player pause];
// 暂停动画
[self.iconView.layer pauseAnimate];
// 停止进度定时器
[self stopProgressTimer];
} else {
[self.player play];
// 继续动画
[self.iconView.layer resumeAnimate];
// 添加进度定时器
[self startProgressTimer];
}
}
- 暂停/继续核心动画根控制器没什么关系,抽取分类CALayer+GGAnimate
- (void)pauseAnimate
{
CFTimeInterval pausedTime = [self convertTime:CACurrentMediaTime() fromLayer:nil];
self.speed = 0.0;
self.timeOffset = pausedTime;
}
- (void)resumeAnimate
{
CFTimeInterval pausedTime = [self timeOffset];
self.speed = 1.0;
self.timeOffset = 0.0;
self.beginTime = 0.0;
CFTimeInterval timeSincePause = [self convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
self.beginTime = timeSincePause;
}
六 添加歌词的 View
- 歌词的 View 为一个UIScrollView
- 根据偏移量不同,变化 view 的透明度
- 遵守UIScrollViewDelegate
- 根据偏移量不同,变化 view 的透明度
#pragma mark - 实现LrcView的代理方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 1.计算scrollView偏移量
CGFloat offsetRatio = scrollView.contentOffset.x / scrollView.bounds.size.width;
// 2.设置歌词的Label和iconView的透明度
self.iconView.alpha = 1 - offsetRatio;
self.lrcLabel.alpha = 1 - offsetRatio;
}
歌词展示用 tableview 实现GGLrcView
- 初始化出来就是一个tableview
- (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self setupTableView]; } return self; }
- 添加 tableview
- (void)setupTableView { // 1.创建tableView UITableView *tableView = [[UITableView alloc] init]; self.tableView = tableView; // 2.添加到歌词的View中 [self addSubview:tableView]; // 3.设置tableView的属性 self.tableView.dataSource = self; self.tableView.rowHeight = 35; }
UIScrollView中使用 Autolayout
- 注意点:添加约束,必须要多添加2个约束(距离右边和下边)
- (void)layoutSubviews
{
[super layoutSubviews];
// 给tableView添加约束
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_top);
make.left.equalTo(self.mas_left).offset(self.bounds.size.width);
make.height.equalTo(self.mas_height);
make.width.equalTo(self.mas_width);
make.bottom.equalTo(self.mas_bottom);
make.right.equalTo(self.mas_right);
}];
// 清除tableView的背景颜色和边线
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// 设置tableView的上下的内边距
self.tableView.contentInset = UIEdgeInsetsMake(self.bounds.size.height * 0.5, 0, self.bounds.size.height * 0.5, 0);
}
- 实现tableview 的数据源方法
#pragma mark - 实现tableView的数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"LrcCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
// 设置cell的背景
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// 设置label的属性
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont systemFontOfSize:14.0];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
cell.textLabel.text = @"测试数据123";
return cell;
}
七 歌词的解析
- 字典转模型(一句歌词转成模型)GGLrcLine
/** 显示的歌词文字 */
@property (nonatomic, copy) NSString *text;
/** 时间 */
@property (nonatomic, assign) NSTimeInterval time;
- 模型对外提供下面方法
- (instancetype)initWithLrcString:(NSString *)lrcString
{
if (self = [super init]) {
// [01:20.74]想这样没担忧 唱着歌 一直走
NSArray *lrclineArray = [lrcString componentsSeparatedByString:@"]"];
self.text = lrclineArray[1];
self.time = [self timeWithString:[lrclineArray[0] substringFromIndex:1]];
}
return self;
}
- 时间需要解析成秒,抽取为方法
- (NSTimeInterval)timeWithString:(NSString *)timeString
{
// 01:20.74
NSArray *timeArray = [timeString componentsSeparatedByString:@":"];
NSInteger min = [timeArray[0] integerValue];
NSInteger second = [[timeArray[1] componentsSeparatedByString:@"."][0] integerValue];
NSInteger haomiao = [[timeArray[1] componentsSeparatedByString:@"."][1] integerValue];
return min * 60 + second + haomiao * 0.01;
}
+ (instancetype)lrcLineWithLrcString:(NSString *)lrcString
{
return [[self alloc] initWithLrcString:lrcString];
}
- 解析歌词抽取工具类
+ (NSArray *)lrcToolWithLrcName:(NSString *)lrcName
{
// 1.获取歌词的路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:lrcName ofType:nil];
// 2.读取该文件中的歌词
NSString *lrcString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
// 3.获取歌词的数组
NSArray *lrcArray = [lrcString componentsSeparatedByString:@"\n"];
// 4.将一句歌词转成模型对象,放入到一个数组中
NSMutableArray *tempArray = [NSMutableArray array];
for (NSString *lrclineString in lrcArray) {
// 4.1.过滤不需要的歌词的行
if ([lrclineString hasPrefix:@"[ti:"] || [lrclineString hasPrefix:@"[ar:"] || [lrclineString hasPrefix:@"[al:"] || ![lrclineString hasPrefix:@"["]) {
continue;
}
// 4.2.解析每一句歌词转成模型对象
GGLrcLine *lrcLine = [GGLrcLine lrcLineWithLrcString:lrclineString];
[tempArray addObject:lrcLine];
}
return tempArray;
}
- 重写 set 方法
#pragma mark - 重写setLrcName的方法
- (void)setLrcName:(NSString *)lrcName
{
_lrcName = lrcName;
// 解析歌词
self.lrcLines = [GGLrcTool lrcToolWithLrcName:lrcName];
// 刷新列表
[self.tableView reloadData];
// 让tableView滚动到最上面
[self.tableView setContentOffset:CGPointMake(0, - self.tableView.bounds.size.height * 0.5) animated:YES];
}
八 将当前播放时间实时传递给LrcView
- 建一个歌词定时器
/** 歌词的定时器 */
@property (nonatomic, strong) CADisplayLink *lrcTimer;
- 对歌词定时器的操作
#pragma mark 歌词的定时器
- (void)startLrcTimer
{
self.lrcTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateLrcInfo)];
[self.lrcTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)stopLrcTimer
{
[self.lrcTimer invalidate];
self.lrcTimer = nil;
}
- (void)updateLrcInfo
{
self.lrcView.currentTime = self.player.currentTime;
}
- 拿到实时时间
- 根据当前播放时间, 让歌词滚到正确的位置
#pragma mark - 重写setCurrentTime方法
- (void)setCurrentTime:(NSTimeInterval)currentTime
{
_currentTime = currentTime;
// 找出需要显示的歌词
NSInteger count = self.lrcLines.count;
for (int i = 0; i < count; i++) {
// 1.拿到i位置的歌词
GGLrcLine *currentLrcLine = self.lrcLines[i];
// 2.拿出i+1位置的歌词
NSInteger nextIndex = i + 1;
if (nextIndex >= count) return;
GGLrcLine *nextLrcLine = self.lrcLines[nextIndex];
// 3.当前时间大于i位置歌词的时间并且小于i+1位置的歌词的时间
if (currentTime >= currentLrcLine.time && currentTime < nextLrcLine.time && self.currentIndex != i) {
/*
[01:03.45]你是我的小呀小苹果儿 63.45 63.46 64.43 i 12
[01:07.06]就像天边最美的云朵 67.06 13
*/
// 计算i位置的IndexPath
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
NSIndexPath *previousPath = [NSIndexPath indexPathForRow:self.currentIndex inSection:0];
// 记录i位置的下标
self.currentIndex = i;
// 刷新i位置的cell(播放时字体变大)
[self.tableView reloadRowsAtIndexPaths:@[indexPath, previousPath] withRowAnimation:UITableViewRowAnimationNone];
// 让tableView的i位置的cell,滚动到中间位置
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
// 设置外面的歌词
self.lrcLabel.text = currentLrcLine.text;
}
// 4.当正在播放某一个歌词(self.currentIndex == i)
if (self.currentIndex == i) {
// 4.1.计算当前已经播放的比例
CGFloat progress = (currentTime - currentLrcLine.time) / (nextLrcLine.time - currentLrcLine.time);
// 4.2.告知当前的歌词的Label进度
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
GGLrcCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.lrcLabel.progress = progress;
// 4.3.改变外面的歌词Label的进度
self.lrcLabel.progress = progress;
}
}
}
- 刷新数据,播放时字体变大
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
GGLrcCell *cell = [GGLrcCell lrcCellWithTableView:tableView];
if (indexPath.row == self.currentIndex) {
cell.lrcLabel.font = [UIFont systemFontOfSize:18.0];
} else {
cell.lrcLabel.font = [UIFont systemFontOfSize:14.0];
cell.lrcLabel.progress = 0;
}
// 2.给cell设置数据
GGLrcLine *lrcline = self.lrcLines[indexPath.row];
cell.lrcLabel.text = lrcline.text;
return cell;
}
自定义 Label,实现 Label 按播放进度渐变
- 重绘一下 Label
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGRect drawRect = CGRectMake(0, 0, rect.size.width * self.progress, rect.size.height); [[UIColor greenColor] set]; // UIRectFill(drawRect); // R = S * Da S是现在正在画的内容透明为1,Da 之前 label 内容的透明度 UIRectFillUsingBlendMode(drawRect, kCGBlendModeSourceIn); // 文字渐变 }
- 实时调用
- (void)setProgress:(CGFloat)progress { _progress = progress; [self setNeedsDisplay]; }
将Label 添加到 cell 中GGLrcCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
// 1.创建自定义的Label
GGLrcLabel *lrcLabel = [[GGLrcLabel alloc] init];
// 2.添加cell中
[self.contentView addSubview:lrcLabel];
// 3.给自定义的label添加约束
[lrcLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.contentView);
}];
// 4.设置label的属性
lrcLabel.textColor = [UIColor whiteColor];
lrcLabel.font = [UIFont systemFontOfSize:14.0];
// 5.设置cell的属性
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
// 6.让成员属性的lrcLabel指向对象
self.lrcLabel = lrcLabel;
}
return self;
}
- 播放页面显示歌词
// 歌词的Label
@property (weak, nonatomic) IBOutlet GGLrcLabel *lrcLabel;
// 5.将外面显示歌词的Label的对象,赋值给lrcView的引用
self.lrcView.lrcLabel = self.lrcLabel;
注意:切换歌曲,刷新 i 位置的 cell 时会报错(上一首歌词量与下一首歌词量不同)
// 计算i位置的IndexPath
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
NSArray *indexPaths = nil;
if (self.currentIndex >= count) {
indexPaths = @[indexPath];
} else {
NSIndexPath *previousPath = [NSIndexPath indexPathForRow:self.currentIndex inSection:0];
indexPaths = @[indexPath, previousPath];
}
九 音乐后台播放
1.开启后台模式
2.设置音频会话模式
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1.获取音频会话
AVAudioSession *session = [AVAudioSession sharedInstance];
// 2.设置音频会话的类型
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
// 3.激活音频会话(静音状态依然可以播放)
[session setActive:YES error:nil];
return YES;
}
- 设置锁屏界面
#pragma mark - 设置锁屏界面的信息
- (void)setupLockScreenInfo
{
// 1.拿到当前播放的歌曲
GGMusic *playingMusic = [GGMusicTool playingMusic];
// 2.设置锁屏界面的内容
// 2.1.获取锁屏界面中心
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
// 2.2.设置显示的信息
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 2.2.1.设置歌曲名称
[dict setValue:playingMusic.name forKey:MPMediaItemPropertyAlbumTitle];
// 2.2.2.设置歌手名称
[dict setValue:playingMusic.singer forKey:MPMediaItemPropertyArtist];
// 2.2.3.设置专辑封面
UIImage *image = [UIImage imageNamed:playingMusic.icon];
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:image];
[dict setValue:artwork forKey:MPMediaItemPropertyArtwork];
// 2.2.4.设置歌曲的总时长
[dict setValue:@(self.player.duration) forKey:MPMediaItemPropertyPlaybackDuration];
infoCenter.nowPlayingInfo = dict;
// 2.3.让应用程序可以接受远程事件
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
- 处理远程事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
case UIEventSubtypeRemoteControlPause:
[self playOrPauseMusic:self.playOrPauseBtn];
break;
case UIEventSubtypeRemoteControlNextTrack:
[self nextMusic];
break;
case UIEventSubtypeRemoteControlPreviousTrack:
[self previousMusic];
break;
default:
break;
}
}