2016-11-24 72 views
0

我需要读取SMPL块内的dwStartdwEnd属性,因为这些点应指定样本中循环的起点和终点。 我将我的Directwave库转换为Bitwig的.multisample格式,所以我的应用程序不需要播放WAV文件。它只是需要读取循环点,因此它可以被添加到看起来像这样的XML:如何用C#读取WAV文件的SMPL块?

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<multisample name="Test Bell"> 
    <generator>Bitwig Studio</generator> 
    <category>Bell</category> 
    <creator>John</creator> 
    <description>Misc</description> 
    <layer name="Default"> 
     <sample file="Bell_004 - C3.wav" gain="0.00" sample-start="0.000" sample-stop="88048.000"> 
      <key track="true" tune="0.00"> 
       <velocity /> 
       <loop mode="sustain" start="58709.000" stop="88048.000" /> 
      </key> 
     </sample> 
    </layer> 
</multisample> 

UPDATE: 马克·希思的代码工作找到KONTAKT WAV文件的SMPL块和循环点但它并没有发现由DirectWave创建例如这个文件中的WAV文件的SMPL块: http://stash.reaper.fm/28963/Flute_006_C3.wav

我用下面的代码,而且只发现了一个研究所块。如果没有smpl块,我如何找到开始和结束循环点?

var smp = reader.ExtraChunks.Where(ec => ec.IdentifierAsString != null); 
      foreach (var x in smp) 
      { 
       MessageBox.Show(x.IdentifierAsString.ToString()); 
      } 

回答

1

您可以使用NAudio WaveFileReader来探索额外的块。以下是“smpl”块的一些代码:

var wavFilePath = @"E:\Recording\sfz\Equinox Steinway D\SteinwayDmA#0.wav"; 
using (var reader = new WaveFileReader(wavFilePath)) 
{ 
    var smp = reader.ExtraChunks.FirstOrDefault(ec => ec.IdentifierAsString == "smpl"); 
    if (smp != null) 
    { 
     var chunkData = reader.GetChunkData(smp); 
     // https://sites.google.com/site/musicgapi/technical-documents/wav-file-format#smpl 
     var midiNote = BitConverter.ToInt32(chunkData,12); 
     var numberOfSamples = BitConverter.ToInt32(chunkData,28); 
     Console.WriteLine($"MIDI {midiNote}, {numberOfSamples} samples"); 
     int offset = 36; 
     for (int n = 0; n < numberOfSamples; n++) 
     { 
      var cuePointId = BitConverter.ToInt32(chunkData,offset); 
      var type = BitConverter.ToInt32(chunkData, offset + 4); // 0 = loop forward, 1 = alternating loop, 2 = reverse 

      var start = BitConverter.ToInt32(chunkData, offset + 8); 
      var end = BitConverter.ToInt32(chunkData, offset + 12); 
      var fraction = BitConverter.ToInt32(chunkData, offset + 16); 
      var playCount = BitConverter.ToInt32(chunkData, offset + 20); 
      Console.WriteLine($"Sample {cuePointId} Start {start} End {end}"); 
      offset+= 24; 
     } 
    } 
} 
+0

感谢您的解决方案Mark。当在几个Wav文件上测试你的代码时,我意识到我的一些Wav文件没有SMPL块,即使它们在加载到采样器(Bitwig/FL Studio)时有循环点。我使用了_for loop_和** IdentifierAsString **遍历块的集合,只发现**“inst”**?是否有可能将循环点放入另一个块中? – user3441364

+0

当然,循环点可能存储在一个块中有许多方法。例如ACID循环有它们自己的块格式。你需要做一些研究/反向工程来找出一个块内的东西 –