MIDI信息隐藏(MATLAB,信息隐藏与数字水印实验)

一、MIDI简介

MIDI(Musical Instrument Digital Interface,乐器数字接口),电子乐器制造商们建立的通信标准,辅助音乐创作、确定电脑音乐程序,用音符的数字控制信号来记录音乐。

一个标准MIDI文件基本上由两部分组成:头块和音轨块。

头块用来描述整个MIDI文件基本信息。

音轨块则包含一系列由MIDI消息构成的MIDI数据流。原则上,可为某种声音、某种乐谱或某种乐器等分配一个音轨块。

MIDI文件中前四个字节是ASCI1字符"MThd" ,用来判断该文件是否为Midi文件,而随后的四个字节指明文件头描述部分的字节数,它总是6,所以一定是"00 00 00 06"。
随后的ff ff nn nn dd dd中的nn nn表示指定轨道数,也就是实际音轨数加上一个全局音轨。

头块之后剩下的文件部分是一个或多个音轨块,每一个音轨块格式见下表。
在这里插入图片描述

每一个MIDI事件的构成:
MIDI事件= <delta time> <MIDI消息>

< delta time>采用可变长编码,它决定了其后的MIDI消息被执行的时间。一个MIDI 消息由一个状态字节及多个数据字节构成。MIDI消息根据性质可分为通道消息 (Channel Message)和系统消息(System Message)两大类。
通道消息对单一的MIDI Channel起作用,其Channel是利用状态字节的低4位来表示,可从0~15共有16个Channel。通道消息又分为声音消息和模式消息。声音消息用于控制合成器的声音产生。模式消息则为最多达16条通道分配声音关系,包括设定单音模式或复音模式等。

MIDI文件的声音消息有7种,见下表。
在这里插入图片描述
改变MIDI音乐文件的部分声音消息并不影响MIDI文件的听觉效果,通过实验,
改变 声音开启 的最低位比特、乐器编号 的最低位比特和 通道触动压力 的低4比特位,
都不会引起听觉差异,因此可在这三种声音消息中嵌入水印信息。

若(s[i]&0xf0) =0x90,十六进制90转十进制为144,转二进制为1001 0000
则在第i+2个字节s[i+2]中嵌入1比特水印信息,表示修改声音开启的最低位。

若(s[i]&0xf0) =0xc0,c0=192=1100 0000
则在第i+1个字节s[i+1]中嵌入1比特水印信息,表示修改乐器编号的最低位比特。

若(s[i]&0xf0) =0xd0,d0=208=1101 0000=16+64+128
则在第i+1个字节s[i+1]中嵌入4比特水印信息,表示修改通道触动压力的低4比特位。

二、MIDI隐藏代码

目的:在a.txt中写入“123456789”藏入love.mid后得到midihide.mid

clear;
clc;
hidefid=fopen('a.txt','r');
[msg,count]=fread(hidefid,inf,'ubit1');
fid=fopen('love.mid','r');
[wa,length]=fread(fid,inf,'uint8');
fclose(hidefid);
fclose(fid);
modcount=1;
p=1;
for i=1:length
    if bitand(wa(i,1),240)==144&&p<=count % 240=1111 0000 144=1001 0000
        wa(i+2,1)=bitset(wa(i+2,1),1,msg(p,1)); % msg(行,列)
        p=p+1;
        i=i+3;
        modcount=modcount+1;
    elseif bitand(wa(i,1),240)==192&&p<=count % 1100 0000
          wa(i+1,1)=bitset(wa(i+1,1),1,msg(p,1));
          p=p+1;
          i=i+2;
          modcount=modcount+1;
    elseif bitand(wa(i,1),240)==208&&p<=count-3 % 必须足够4位才可以隐藏
        wa(i+1,1)=bitset(wa(i+1,1),1,msg(p,1));
        wa(i+1,1)=bitset(wa(i+1,1),2,msg(p+1,1));
        wa(i+1,1)=bitset(wa(i+1,1),3,msg(p+2,1));  
        wa(i+1,1)=bitset(wa(i+1,1),4,msg(p+3,1));    
        p=p+4;
        i=i+2;
        modcount=modcount+1;
    else
        i=i+1;
    end
end
fid=fopen('midihide.mid','a');
fwrite(fid,wa);
fclose(fid);

三、MIDI提取代码

clear;
clc;
fid=fopen('midihide.mid','r');
[wa,length]=fread(fid,inf,'uint8');
getfid=fopen('midget.txt','a');
fclose(fid);
count=72; % 这个值的选择依据隐藏的数据,如果是9位数字或字母就是9×8=72,如果是2个汉字就是2×16=32
p=1;
for i=1:length
    if(bitand(wa(i,1),240)==144)&&(p<=count)
        fwrite(getfid,bitget(wa(i+2,1),1),'ubit1');
        i=i+3;
            if p==count
                break;
            end
        p=p+1;
    elseif(bitand(wa(i,1),240)==192)&&(p<=count)
        fwrite(getfid,bitget(wa(i+1,1),1),'ubit1');
         i=i+2;
            if p==count
                break;
            end
        p=p+1;
      elseif(bitand(wa(i,1),240)==208)&&(p<=count-3)
          fwrite(getfid,bitget(wa(i+1,1),1),'ubit1');
          fwrite(getfid,bitget(wa(i+1,1),2),'ubit1');
          fwrite(getfid,bitget(wa(i+1,1),3),'ubit1');
          fwrite(getfid,bitget(wa(i+1,1),4),'ubit1');
          i=i+2;
          if p==count
               break;
          end
          p=p+4;
    end
end
fclose(getfid);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值