home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2001 December (DVD) / VPR0112A.ISO / OLS / WAVKNIFE / wavknife.lzh / src.lzh / wkfrm.pas < prev   
Pascal/Delphi Source File  |  2001-02-19  |  56KB  |  1,632 lines

  1. unit wkfrm;
  2. ///////////////////////////////////////////////////////////////
  3. //             waveファイルの録音・切り出し・結合ツール
  4. //             リアルタイム切り出しを断念したので、その代替品
  5. //
  6. //             susumuk@fa.mbn.or.jp
  7. //             http://www14.big.or.jp/~kawamura/
  8. //
  9. //             ソースコードともに、改変・再配布は自由です。
  10. //             何かありましたら上のアドレスまで。
  11. //
  12. //             バージョン履歴
  13. //             v0.1 1997.11.25  WinDAT(非公開,リアルタイム)がよく
  14. //                  エラーで止まるので、ついに作成
  15. //             v0.2 1997.11.30  Excel VBAからのSendKeyが使えるように、
  16. //                  キーボードショートカットを追加
  17. //                  (早速研究用として活躍開始!!)
  18. //             v0.3 1997.12.4   遅い機種でどうしても動かないので、
  19. //                  MediaPlayer(MCI)を使うよう変更
  20. //                  ただ、やはりMCIでは役不足な機能(複数のサウンドカード)
  21. //                  があるので、
  22. //                  /expert オプションを付けておいた。
  23. //                  (このコマンドラインオプションで、従来の利用が可能)
  24. //             v0.4 1997.12.10 開発再開 12.14 公開
  25. //                  MediaPlayerを使った場合の機能を充実。
  26. //                  切り出し時に、0点補正の機能を利用できるようにした。
  27. //                  (あまり想定していないが)CDプレーヤが起動できるようにした。
  28. //                  v0.3のとき発見していたバグを忘れていて、非常に手間取る。
  29. //             v0.5 1997.12.14 録音時間の制限が小さすぎる不具合を修正
  30. //             v0.6 1998.2.11 録音時間表示の不具合修正
  31. //                  2G以上のドライブ(FAT or NTFS)で正しい空き容量が取得できるようにした
  32. //                  ただし、今のところネットワークドライブに関しては空き容量を
  33. //                  正しく取得することはできません(NetBIOSの制限)
  34. //                  1998.3.22 OSR2以前のバージョンでは利用できないことが判明
  35. //             v0.7 1998.5.6 時刻表示のバグを修正
  36. //                  OSR2専用ルーチンを作った(OSR2Func)
  37. //             v0.8 2001.1.17 Delphi5に移植。
  38. //                  OSR2専用ルーチンを外す。
  39. //                  MCIの制限で4G以上のWAVEファイルは作れないこと、
  40. //                  FileSystemによっては4G以上のファイルが正しく扱えないことがあるので、
  41. //                  4G以上のファイルは生成できないようにした。
  42.  
  43. interface
  44.  
  45. uses
  46.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  47.   StdCtrls, Spin, shlabout, BrowsDlg, Buttons, ComCtrls,
  48.   ExtCtrls, Menus, mmsystem, SHELLAPI, MPlayer,Math;
  49.  
  50. const
  51.       MAX_BUFFERS=2;               // 2重バッファ
  52.       DATABLOCK_SIZE=8192;        // データブロックサイズ
  53.  
  54.       USR_INBLOCK=WM_USER+101;     // ブロックがいっぱいになったメッセージ
  55.       MSG_LEN=255;
  56.       HEAP_ZERO_MEMORY=$8;
  57.  
  58.       trigdelay=512;
  59.  
  60. type ULARGE_INTEGER = record
  61.         Part:array[0..2] of WORD;
  62.         PartHi:SmallInt;
  63.      end;
  64.  
  65. type
  66.   TForm1 = class(TForm)
  67.     MainMenu1: TMainMenu;
  68.     File1: TMenuItem;
  69.     Help1: TMenuItem;
  70.     KR1: TMenuItem;
  71.     KC1: TMenuItem;
  72.     KA1: TMenuItem;
  73.     Exit1: TMenuItem;
  74.     KF1: TMenuItem;
  75.     KS1: TMenuItem;
  76.     KS2: TMenuItem;
  77.     KS3: TMenuItem;
  78.     K1: TMenuItem;
  79.     K2: TMenuItem;
  80.     About1: TMenuItem;
  81.     Panel1: TPanel;
  82.     PageControl1: TPageControl;
  83.     TabSheet1: TTabSheet;
  84.     TabSheet2: TTabSheet;
  85.     TabSheet3: TTabSheet;
  86.     Panel2: TPanel;
  87.     Panel4: TPanel;
  88.     Image1: TImage;
  89.     Label1: TLabel;
  90.     Panel3: TPanel;
  91.     Panel5: TPanel;
  92.     Label2: TLabel;
  93.     BitBtn1: TBitBtn;
  94.     BitBtn2: TBitBtn;
  95.     BitBtn3: TBitBtn;
  96.     BitBtn4: TBitBtn;
  97.     BitBtn5: TBitBtn;
  98.     CheckBox1: TCheckBox;
  99.     BrowseDialog1: TBrowseDialog;
  100.     ShellAboutDialog1: TShellAboutDialog;
  101.     Label3: TLabel;
  102.     Label4: TLabel;
  103.     Label5: TLabel;
  104.     ListBox1: TListBox;
  105.     Label6: TLabel;
  106.     Edit1: TEdit;
  107.     Button1: TButton;
  108.     ComboBox2: TComboBox;
  109.     SpinEdit1: TSpinEdit;
  110.     Label8: TLabel;
  111.     SpinEdit2: TSpinEdit;
  112.     SpinEdit3: TSpinEdit;
  113.     Label9: TLabel;
  114.     Label10: TLabel;
  115.     Button2: TButton;
  116.     Label12: TLabel;
  117.     Label13: TLabel;
  118.     Label14: TLabel;
  119.     Button3: TButton;
  120.     Label15: TLabel;
  121.     Edit2: TEdit;
  122.     Button4: TButton;
  123.     Button5: TButton;
  124.     Button6: TButton;
  125.     Button7: TButton;
  126.     Button8: TButton;
  127.     Button9: TButton;
  128.     Button10: TButton;
  129.     SaveDialog1: TSaveDialog;
  130.     OpenDialog1: TOpenDialog;
  131.     GroupBox1: TGroupBox;
  132.     RadioButton1: TRadioButton;
  133.     RadioButton2: TRadioButton;
  134.     Button11: TButton;
  135.     Edit3: TEdit;
  136.     Label11: TLabel;
  137.     Button12: TButton;
  138.     Label16: TLabel;
  139.     SpinEdit4: TSpinEdit;
  140.     SpinEdit5: TSpinEdit;
  141.     SpinEdit6: TSpinEdit;
  142.     Label17: TLabel;
  143.     Label18: TLabel;
  144.     Label19: TLabel;
  145.     Label20: TLabel;
  146.     ComboBox3: TComboBox;
  147.     Label21: TLabel;
  148.     ComboBox4: TComboBox;
  149.     Label22: TLabel;
  150.     SpinEdit7: TSpinEdit;
  151.     Label23: TLabel;
  152.     SpinEdit8: TSpinEdit;
  153.     Label24: TLabel;
  154.     Label25: TLabel;
  155.     Label26: TLabel;
  156.     Edit4: TEdit;
  157.     Button13: TButton;
  158.     Label27: TLabel;
  159.     OpenDialog2: TOpenDialog;
  160.     OpenDialog3: TOpenDialog;
  161.     CheckBox4: TCheckBox;
  162.     BrowseDialog2: TBrowseDialog;
  163.     Button14: TButton;
  164.     Timer1: TTimer;
  165.     N1: TMenuItem;
  166.     KV1: TMenuItem;
  167.     Label33: TLabel;
  168.     Label34: TLabel;
  169.     Timer2: TTimer;
  170.     GroupBox2: TGroupBox;
  171.     Label30: TLabel;
  172.     Label32: TLabel;
  173.     Label31: TLabel;
  174.     Label29: TLabel;
  175.     CheckBox5: TCheckBox;
  176.     CheckBox6: TCheckBox;
  177.     MediaPlayer1: TMediaPlayer;
  178.     Label35: TLabel;
  179.     Label36: TLabel;
  180.     Label37: TLabel;
  181.     Label38: TLabel;
  182.     Label39: TLabel;
  183.     Label40: TLabel;
  184.     Label41: TLabel;
  185.     CDPlayerC1: TMenuItem;
  186.     SpeedButton1: TSpeedButton;
  187.     SpeedButton2: TSpeedButton;
  188.     SpeedButton3: TSpeedButton;
  189.     TrackBar951: TTrackBar;
  190.     procedure About1Click(Sender: TObject);
  191.     procedure Button1Click(Sender: TObject);
  192.     procedure Button13Click(Sender: TObject);
  193.     procedure Button12Click(Sender: TObject);
  194.     procedure Button2Click(Sender: TObject);
  195.     procedure Button3Click(Sender: TObject);
  196.     procedure Exit1Click(Sender: TObject);
  197.     procedure KF1Click(Sender: TObject);
  198.     procedure KS2Click(Sender: TObject);
  199.     procedure K1Click(Sender: TObject);
  200.     procedure FormCreate(Sender: TObject);
  201.     procedure Button4Click(Sender: TObject);
  202.     procedure Button5Click(Sender: TObject);
  203.     procedure Button7Click(Sender: TObject);
  204.     procedure Button6Click(Sender: TObject);
  205.     procedure Button8Click(Sender: TObject);
  206.     procedure Button9Click(Sender: TObject);
  207.     procedure RadioButton2Click(Sender: TObject);
  208.     procedure RadioButton1Click(Sender: TObject);
  209.     procedure Edit1Change(Sender: TObject);
  210.     procedure CheckBox4Click(Sender: TObject);
  211.     procedure Button14Click(Sender: TObject);
  212.     procedure Timer1Timer(Sender: TObject);
  213.     procedure KV1Click(Sender: TObject);
  214.     procedure BitBtn5Click(Sender: TObject);
  215.     procedure BitBtn4Click(Sender: TObject);
  216.     procedure KS3Click(Sender: TObject);
  217.     procedure Timer2Timer(Sender: TObject);
  218.     procedure Button10Click(Sender: TObject);
  219.     procedure SpinEdit5Change(Sender: TObject);
  220.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  221.     procedure KS1Click(Sender: TObject);
  222.     procedure CheckBox1Click(Sender: TObject);
  223.     procedure CDPlayerC1Click(Sender: TObject);
  224.     procedure SpeedButton1Click(Sender: TObject);
  225.     procedure SpeedButton2Click(Sender: TObject);
  226.     procedure SpeedButton3Click(Sender: TObject);
  227.     procedure ComboBox2Change(Sender: TObject);
  228.   private
  229.     { Private 宣言 }
  230.     waveinDevID:integer;
  231.     Fzeroadjdata:array [1..2] of integer;    //左 or 右チャンネル
  232.     waveinfs:TFileStream;
  233.     tempms:TMemoryStream;
  234.     ch,freq,bits:integer;
  235.     _breakflag:integer;
  236.     recordingstatus:integer;
  237.     procedure DiskFreeCalcProc;
  238.     procedure WaveStopProc;
  239.     procedure HeaderCreate(fs:TFileStream;FmtComboBox:TComboBox);
  240.     procedure HeaderCorrect(fs:TFileStream);
  241.     procedure cuttingproc;
  242.     procedure SetCutFileName(s:string);
  243.     procedure SetCmbFiles(StringList:TStrings);
  244.     procedure recordingbuttonclick;
  245.     function Getzeroadjdata(i:integer):integer;
  246.     procedure Setzeroadjdata(i,value:integer);
  247.  
  248.     // エクスプローラからのDrag&Dropを許可する
  249.     procedure WMDropFiles(var msg: TWMDROPFILES); {メソッドの宣言}
  250.     message WM_DROPFILES;                         {受け取るメッセージ}
  251.  
  252.   public
  253.     { Public 宣言 }
  254.     property breakflag: integer read _breakflag write _breakflag;
  255.     property zeroadjdata[i:integer]: integer read Getzeroadjdata write Setzeroadjdata;
  256.   protected
  257.     procedure CreateParams(var Params: TCreateParams); override;
  258.   end;
  259.  
  260. var
  261.   Form1: TForm1;
  262.  
  263. implementation
  264.  
  265. uses adjfrm, cbfrm, cutfrm;
  266.  
  267. {$R *.DFM}
  268.  
  269. procedure TForm1.About1Click(Sender: TObject);
  270. begin
  271.      ShellAboutDialog1.Execute;
  272. end;
  273.  
  274. procedure TForm1.Button1Click(Sender: TObject);
  275. var s:string;
  276. begin
  277.      BrowseDialog1.Directory:=Edit1.Text;
  278.      if BrowseDialog1.Execute then
  279.      begin
  280.         s:=BrowseDialog1.Directory;
  281.         if s[length(s)]='\' then Delete(s,length(s),1);
  282.         Edit1.Text:=s;
  283.      end;
  284. end;
  285.  
  286. procedure TForm1.Button13Click(Sender: TObject);
  287. var s:string;
  288. begin
  289.      BrowseDialog2.Directory:=Edit4.Text;
  290.      if BrowseDialog2.Execute then
  291.      begin
  292.         s:=BrowseDialog2.Directory;
  293.         if s[length(s)]='\' then Delete(s,length(s),1);
  294.         Edit4.Text:=s;
  295.      end;
  296. end;
  297.  
  298. procedure TForm1.Button12Click(Sender: TObject);
  299. begin
  300.      if OpenDialog2.Execute then
  301.         SetCutFileName(OpenDialog2.FileName);
  302. end;
  303.  
  304. procedure TForm1.SetCutFileName(s:string);
  305. var fs:TFileStream;
  306.     k:integer;
  307.     ckid:array[0..3] of Char;
  308.     waveformatrec1:TWAVEFORMATEX;
  309. begin
  310.         // Waveファイルの形式をチェックし、
  311.         // 「形式」を変更する
  312.         if UpperCase(ExtractFileExt(s))='.WAV' then
  313.         begin
  314.              fs:=TFileStream.Create(s,fmOpenRead);
  315.              try
  316.                 // waveファイルの読み取りには本来mmio関数を使うべきだが
  317.                 // これを使うと面倒なので、ここでは4バイトずつ読んで、
  318.                 // 'fmt 'チャンクを探す
  319.                 fs.Seek(0,soFromBeginning);
  320.                 k:=0;
  321.                 ckid:='    ';
  322.                 while not (ckid='fmt ') and (k<200) do
  323.                 begin
  324.                      fs.Read(ckid,4);
  325.                      inc(k);
  326.                 end;
  327.                 // 200バイトも探したのに、見つからなかった(壊れてる??)
  328.                 if k=200 then
  329.                 begin
  330.                      Application.MessageBox('サポートできない形式です。',
  331.                                             'Error',mb_IconHand or mb_Ok);
  332.                      exit;
  333.                 end;
  334.                 fs.Seek(4,soFromCurrent);
  335.                 fs.Read(waveformatrec1,sizeof(TWAVEFORMATEX));
  336.                 with waveformatrec1 do
  337.                 begin
  338.                      if (wFormatTag<>WAVE_FORMAT_PCM) then
  339.                      begin
  340.                           Application.MessageBox('サポートできない形式です。',
  341.                                                  'Error',mb_IconHand or mb_Ok);
  342.                           exit;
  343.                      end;
  344.                      case (nSamplesPerSec) of
  345.                      48000: k:=1;
  346.                      44100: k:=2;
  347.                      32000: k:=3;
  348.                      22050: k:=4;
  349.                      11025: k:=5;
  350.                      5000: k:=6;
  351.                      else
  352.                           Application.MessageBox('サポートできない形式です。',
  353.                                                  'Error',mb_IconHand or mb_Ok);
  354.                           exit;
  355.                      end;
  356.                      if (nChannels=1) then k:=6+k;
  357.                      if (wBitsPerSample=8) then k:=12+k;
  358.                 end;
  359.                 ComboBox3.ItemIndex:=k-1;
  360.              finally
  361.                 fs.Free;
  362.              end;
  363.         end;
  364.         Edit3.Text:=s;
  365. end;
  366.  
  367. procedure TForm1.Button2Click(Sender: TObject);
  368. begin
  369.      if SaveDialog1.Execute then
  370.         Edit2.Text:=SaveDialog1.FileName;
  371. end;
  372.  
  373. procedure TForm1.Button3Click(Sender: TObject);
  374. begin
  375.      if OpenDialog3.Execute then
  376.          SetCmbFiles(OpenDialog3.Files);
  377. end;
  378.  
  379. procedure TForm1.SetCmbFiles(StringList:TStrings);
  380. var fs:TFileStream;
  381.     k,i:integer;
  382.     ckid:array[0..3] of Char;
  383.     waveformatrec1:TWAVEFORMATEX;
  384. begin
  385.      begin
  386.         for i:=0 to StringList.Count-1 do
  387.         begin
  388.              // Waveファイルの形式をチェックし、
  389.              // 「形式」を変更する
  390.              if UpperCase(ExtractFileExt(StringList.Strings[i]))='.WAV' then
  391.              begin
  392.                   fs:=TFileStream.Create(StringList.Strings[i],fmOpenRead);
  393.                   try
  394.                      // waveファイルの読み取りには本来mmio関数を使うべきだが
  395.                      // これを使うと面倒なので、ここでは4バイトずつ読んで、
  396.                      // 'fmt 'チャンクを探す
  397.                      fs.Seek(0,soFromBeginning);
  398.                      k:=0;
  399.                      ckid:='    ';
  400.                      while not (ckid='fmt ') and (k<200) do
  401.                      begin
  402.                           fs.Read(ckid,4);
  403.                           inc(k);
  404.                      end;
  405.                      // 200バイトも探したのに、見つからなかった(壊れてる??)
  406.                      if k=200 then
  407.                      begin
  408.                           Application.MessageBox('サポートできない形式です。',
  409.                                                  'Error',mb_IconHand or mb_Ok);
  410.                           exit;
  411.                      end;
  412.                      fs.Seek(4,soFromCurrent);
  413.                      fs.Read(waveformatrec1,sizeof(TWAVEFORMATEX));
  414.                      with waveformatrec1 do
  415.                      begin
  416.                           if (wFormatTag<>WAVE_FORMAT_PCM) then
  417.                           begin
  418.                                Application.MessageBox('サポートできない形式です。',
  419.                                                       'Error',mb_IconHand or mb_Ok);
  420.                                exit;
  421.                           end;
  422.                           case (nSamplesPerSec) of
  423.                           48000: k:=1;
  424.                           44100: k:=2;
  425.                           32000: k:=3;
  426.                           22050: k:=4;
  427.                           11025: k:=5;
  428.                           5000: k:=6;
  429.                           else
  430.                               Application.MessageBox('サポートできない形式です。',
  431.                                                      'Error',mb_IconHand or mb_Ok);
  432.                               exit;
  433.                           end;
  434.                           if (nChannels=1) then k:=k+6;
  435.                           if (wBitsPerSample=8) then k:=k+12;
  436.                      end;
  437.                      if (i>1) and (ComboBox4.ItemIndex<>k-1) then
  438.                      begin
  439.                         if Application.MessageBox('形式の異なるWaveファイルですが、結合しますか?',
  440.                                                   '警告',mb_IconWarning or mb_YesNo)=IDYes then
  441.                            ComboBox4.ItemIndex:=k-1
  442.                         else exit;
  443.                      end
  444.                      else ComboBox4.ItemIndex:=k-1;
  445.                   finally
  446.                      fs.Free;
  447.                   end;
  448.              end;
  449.              ListBox1.Items.Add(StringList.Strings[i]);
  450.         end;
  451.      end;
  452. end;
  453.  
  454. procedure TForm1.Exit1Click(Sender: TObject);
  455. begin
  456.      close;
  457. end;
  458.  
  459. procedure TForm1.KF1Click(Sender: TObject);
  460. begin
  461.      PageControl1.ActivePage:=TabSheet1;
  462. end;
  463.  
  464. procedure TForm1.KS2Click(Sender: TObject);
  465. begin
  466.      PageControl1.ActivePage:=TabSheet2;
  467. end;
  468.  
  469. procedure TForm1.K1Click(Sender: TObject);
  470. begin
  471.      PageControl1.ActivePage:=TabSheet3;
  472. end;
  473.  
  474. procedure TForm1.FormCreate(Sender: TObject);
  475. var path:array[0..259] of Char;
  476.     s:string;
  477.     ii,i:integer;
  478.     wc:TWAVEINCAPS;
  479.     StringList1:TStringList;
  480. begin
  481.      // テンポラリディレクトリの取得設定
  482.      GetTempPath(259,path);
  483.      s:=string(path);
  484.      if s[length(s)]='\' then Delete(s,length(s),1);
  485.      Edit4.Text:=s;
  486.      Edit1.Text:=s;
  487.      Edit3.Text:=s+'\wavkntmp.wav';
  488.  
  489.      // 録音デバイスの情報を取得設定
  490.      ComboBox3.ItemIndex:=1;
  491.      ComboBox4.ItemIndex:=1;
  492.      ii:=WaveInGetNumDevs;
  493.      if ii=0 then
  494.      begin
  495.           Application.MessageBox('録音デバイスが見つかりません。録音はできません。','デバイスエラー',
  496.                                  mb_IconHand or mb_Ok);
  497.           TabSheet1.Visible:=false;
  498.           exit;
  499.      end;
  500.  
  501.      // 録音デバイスの録音可能な範囲を設定
  502.      waveinDevID := WAVE_MAPPER;
  503.      waveInGetDevCaps(waveinDevID,@wc,sizeof(TWAVEINCAPS));
  504.      StringList1:=TStringList.Create;
  505.      try
  506.         StringList1.Sorted:=true;
  507.         with wc do
  508.         begin
  509.              if dwFormats and WAVE_FORMAT_1M08<>0 then StringList1.Add('8bit, Mono, 11kHz');
  510.              if dwFormats and WAVE_FORMAT_1S08<>0 then StringList1.Add('8bit, Stereo, 11kHz');
  511.              if dwFormats and WAVE_FORMAT_1M16<>0 then StringList1.Add('16bit, Mono, 11kHz');
  512.              if dwFormats and WAVE_FORMAT_1S16<>0 then StringList1.Add('16bit, Stereo, 11kHz');
  513.              if dwFormats and WAVE_FORMAT_2M08<>0 then StringList1.Add('8bit, Mono, 22kHz');
  514.              if dwFormats and WAVE_FORMAT_2S08<>0 then StringList1.Add('8bit, Stereo, 22kHz');
  515.              if dwFormats and WAVE_FORMAT_2M16<>0 then StringList1.Add('16bit, Mono, 22kHz');
  516.              if dwFormats and WAVE_FORMAT_2S16<>0 then StringList1.Add('16bit, Stereo, 22kHz');
  517.              if (dwFormats and WAVE_FORMAT_2M08<>0) and (dwFormats and WAVE_FORMAT_4M08<>0)
  518.              then StringList1.Add('8bit, Mono, 32kHz');
  519.              if (dwFormats and WAVE_FORMAT_2S08<>0) and (dwFormats and WAVE_FORMAT_4S08<>0)
  520.              then StringList1.Add('8bit, Stereo, 32kHz');
  521.              if (dwFormats and WAVE_FORMAT_2M16<>0) and (dwFormats and WAVE_FORMAT_4M16<>0)
  522.              then StringList1.Add('16bit, Mono, 32kHz');
  523.              if (dwFormats and WAVE_FORMAT_2S16<>0) and (dwFormats and WAVE_FORMAT_4S16<>0)
  524.              then StringList1.Add('16bit, Stereo, 32kHz');
  525.              if dwFormats and WAVE_FORMAT_4M08<>0 then
  526.              begin
  527.                   StringList1.Add('8bit, Mono, 44.1kHz');
  528.                   StringList1.Add('8bit, Mono, 48kHz');
  529.              end;
  530.              if dwFormats and WAVE_FORMAT_4S08<>0 then
  531.              begin
  532.                   StringList1.Add('8bit, Stereo, 44.1kHz');
  533.                   StringList1.Add('8bit, Stereo, 48kHz');
  534.              end;
  535.              if dwFormats and WAVE_FORMAT_4M16<>0 then
  536.              begin
  537.                   StringList1.Add('16bit, Mono, 44.1kHz');
  538.                   StringList1.Add('16bit, Mono, 48kHz');
  539.              end;
  540.              if dwFormats and WAVE_FORMAT_4S16<>0 then
  541.              begin
  542.                   StringList1.Add('16bit, Stereo, 44.1kHz');
  543.                   StringList1.Add('16bit, Stereo, 48kHz');
  544.              end;
  545.         end;
  546.         ComboBox2.Items.AddStrings(StringList1);
  547.      finally
  548.         StringList1.Free;
  549.      end;
  550.      ComboBox2.ItemIndex:=0;
  551.  
  552.      // ディスクの空き容量を取得
  553.      DiskFreeCalcProc;
  554. end;
  555.  
  556. procedure TForm1.Button4Click(Sender: TObject);
  557. begin
  558.      if ListBox1.ItemIndex>0 then
  559.      begin
  560.         ListBox1.Items.Exchange(0,ListBox1.ItemIndex);
  561.         ListBox1.ItemIndex:=0;
  562.      end;
  563. end;
  564.  
  565. procedure TForm1.Button5Click(Sender: TObject);
  566. var i:integer;
  567. begin
  568.      if ListBox1.ItemIndex>0 then
  569.      begin
  570.         i:=ListBox1.ItemIndex;
  571.         ListBox1.Items.Exchange(i-1,i);
  572.         ListBox1.ItemIndex:=i-1;
  573.      end;
  574. end;
  575.  
  576. procedure TForm1.Button7Click(Sender: TObject);
  577. begin
  578.      if ListBox1.ItemIndex>0 then
  579.      begin
  580.         ListBox1.Items.Exchange(ListBox1.Items.Count-1,ListBox1.ItemIndex);
  581.         ListBox1.ItemIndex:=ListBox1.Items.Count-1;
  582.      end;
  583. end;
  584.  
  585. procedure TForm1.Button6Click(Sender: TObject);
  586. var i:integer;
  587. begin
  588.      if (ListBox1.ItemIndex>0) and
  589.         (ListBox1.ItemIndex<ListBox1.Items.Count-1) then
  590.      begin
  591.         i:=ListBox1.ItemIndex;
  592.         ListBox1.Items.Exchange(i+1,i);
  593.         ListBox1.ItemIndex:=i+1;
  594.      end;
  595. end;
  596.  
  597. procedure TForm1.Button8Click(Sender: TObject);
  598. var i:integer;
  599. begin
  600.      if ListBox1.ItemIndex>0 then
  601.      begin
  602.         i:=ListBox1.ItemIndex;
  603.         ListBox1.Items.Delete(i);
  604.         if (i<ListBox1.Items.Count) then ListBox1.ItemIndex:=i
  605.         else if (i>0) then ListBox1.ItemIndex:=i-1;
  606.      end;
  607. end;
  608.  
  609. procedure TForm1.Button9Click(Sender: TObject);
  610. begin
  611.      ListBox1.Items.Clear;
  612. end;
  613.  
  614. procedure TForm1.RadioButton2Click(Sender: TObject);
  615. begin
  616.      Label22.Enabled:=false;
  617.      Label23.Enabled:=false;
  618.      Label24.Enabled:=false;
  619.      Label25.Enabled:=false;
  620.      SpinEdit7.Enabled:=false;
  621.      SpinEdit8.Enabled:=false;
  622.  
  623.      Label16.Enabled:=true;
  624.      Label17.Enabled:=true;
  625.      Label18.Enabled:=true;
  626.      Label19.Enabled:=true;
  627.      SpinEdit4.Enabled:=true;
  628.      SpinEdit5.Enabled:=true;
  629.      SpinEdit6.Enabled:=true;
  630. end;
  631.  
  632. procedure TForm1.RadioButton1Click(Sender: TObject);
  633. begin
  634.      Label22.Enabled:=true;
  635.      Label23.Enabled:=true;
  636.      Label24.Enabled:=true;
  637.      Label25.Enabled:=true;
  638.      SpinEdit7.Enabled:=true;
  639.      SpinEdit8.Enabled:=true;
  640.  
  641.      Label16.Enabled:=false;
  642.      Label17.Enabled:=false;
  643.      Label18.Enabled:=false;
  644.      Label19.Enabled:=false;
  645.      SpinEdit4.Enabled:=false;
  646.      SpinEdit5.Enabled:=false;
  647.      SpinEdit6.Enabled:=false;
  648. end;
  649.  
  650. procedure TForm1.DiskFreeCalcProc;
  651. var df,df1,df2,df3,cb,cb1,cb2,cb3:comp;
  652.     b:integer;
  653.     path:array[0..259] of Char;
  654. begin
  655.      // 1秒の録音に費やすwaveファイルの大きさを計算
  656.      b:=1;
  657.      if Pos('16bit',ComboBox2.Text)>0 then b:=2;
  658.      if Pos('Stereo',ComboBox2.Text)>0 then b:=b*2;
  659.      if Pos('11kHz',ComboBox2.Text)>0 then b:=b*11025
  660.      else if Pos('22kHz',ComboBox2.Text)>0 then b:=b*22050
  661.      else if Pos('32kHz',ComboBox2.Text)>0 then b:=b*32000
  662.      else if Pos('44.1kHz',ComboBox2.Text)>0 then b:=b*44100
  663.      else if Pos('5kHz',ComboBox2.Text)>0 then b:=b*5000
  664.      else b:=b*48000;
  665.  
  666.      // MediaPlayerコンポーネントを利用
  667.      // MediaPlayerコンポーネントでは、
  668.      // いったんテンポラリファイルを作るので、
  669.      // 制限時間は次のうち、一番小さい値に依存
  670.      // (waveファイルの保存ドライブの空き容量)
  671.      // (テンポラリファイルのドライブの空き容量)
  672.      // (もし、両方同じドライブを利用するときは、空き容量の半分の値)
  673.      // ネットワークドライブは空き容量が取得できないので、
  674.      // とりあえず2Gbに設定。
  675.  
  676.      // waveファイルを保存するドライブの空き容量を取得
  677.      if Copy(Edit1.Text,1,1)='\'
  678.      then df1:=6442450944
  679.      else
  680.      begin
  681.         df1:=DiskFree(ord(UpCase(Edit1.text[1]))-64);
  682.      end;
  683.  
  684.      // テンポラリディレクトリの取得設定
  685.      GetTempPath(260,path);
  686.      // テンポラリファイルを保存するドライブの空き容量を取得
  687.      if path[0]='\'
  688.      then df2:=6442450944
  689.      else
  690.      begin
  691.         df2:=DiskFree(ord(UpCase(path[0]))-64);
  692.      end;
  693.  
  694.      // 切り出したファイルを保存するドライブの空き容量を取得
  695.      if Copy(Edit4.Text,1,1)='\'
  696.      then df3:=6442450944
  697.      else
  698.      begin
  699.         df3:=DiskFree(ord(UpCase(Edit4.text[1]))-64);
  700.      end;
  701.  
  702.      // 同じドライブを利用するときは、それらの1/3または半分の値
  703.      // 切り出す場合 (ver 0.5バグフィックス)
  704.      if CheckBox1.Checked then
  705.      begin
  706.          if ((UpperCase(Copy(Edit1.text,1,1))=string(UpCase(path[0]))) and
  707.              (UpperCase(Copy(Edit4.text,1,1))=string(UpCase(path[0])))) then
  708.          df1:=df1/3
  709.          else if ((UpperCase(Copy(Edit1.text,1,1))=string(UpCase(path[0]))) or
  710.                   (UpperCase(Copy(Edit4.text,1,1))=string(UpCase(path[0])))) then
  711.          df1:=df1/2
  712.          else if (UpperCase(Copy(Edit4.Text,1,1))=string(UpCase(path[0]))) then
  713.          df2:=df2/2
  714.          else if (UpperCase(Copy(Edit1.text,1,1))=UpperCase(Copy(Edit4.text,1,1))) then
  715.          df3:=df3/2;
  716.  
  717.          if df1<df2 then df:=df1 else df:=df2;
  718.          if df3<df then df:=df3;
  719.      end
  720.      // 切り出さない場合
  721.      else
  722.      begin
  723.          if (UpperCase(Copy(Edit1.text,1,1))=string(UpCase(path[0]))) then
  724.          df1:=df1/2;
  725.  
  726.          if df1<df2 then df:=df1 else df:=df2;
  727.      end;
  728.  
  729.      // もし4G以上なら4Gに固定する。
  730.      if df>4294967296 then df := 4294967296;
  731.  
  732.      cb:=df/b;  // 秒数
  733.      cb1:=int(cb/60/60);
  734.      SpinEdit1.MaxValue:=trunc(cb1);
  735.      if SpinEdit1.Value>SpinEdit1.MaxValue then SpinEdit1.Value:=SpinEdit1.MaxValue;
  736.      cb2:=int((cb-cb1*60*60)/60);
  737.      if SpinEdit1.MaxValue=SpinEdit1.Value then SpinEdit2.MaxValue:=trunc(cb2)
  738.                                            else SpinEdit2.MaxValue:=59;
  739.      if (SpinEdit1.MaxValue=SpinEdit1.Value) and
  740.         (SpinEdit2.Value>SpinEdit2.MaxValue) then
  741.         SpinEdit2.Value:=SpinEdit2.MaxValue;
  742.      cb3:=int(cb-((cb1*60)+cb2)*60);
  743.      if SpinEdit2.MaxValue=SpinEdit2.Value then SpinEdit3.MaxValue:=trunc(cb3)
  744.                                            else SpinEdit3.MaxValue:=59;
  745.      if (SpinEdit1.MaxValue=SpinEdit1.Value) and
  746.         (SpinEdit2.MaxValue=SpinEdit2.Value) and
  747.         (SpinEdit3.Value>SpinEdit3.MaxValue) then
  748.         SpinEdit3.Value:=SpinEdit3.MaxValue;
  749.      if SpinEdit1.MaxValue=0 then SpinEdit1.Enabled:=false
  750.                              else SpinEdit1.Enabled:=true;
  751.      if (SpinEdit1.MaxValue=0) and
  752.         (SpinEdit2.MaxValue=0) then SpinEdit2.Enabled:=false
  753.                                else SpinEdit2.Enabled:=true;
  754. end;
  755.  
  756. procedure TForm1.Edit1Change(Sender: TObject);
  757. begin
  758.      DiskFreeCalcProc;
  759. end;
  760.  
  761. procedure TForm1.CheckBox4Click(Sender: TObject);
  762. begin
  763.      if CheckBox4.Checked then
  764.      begin
  765.           Button14.Enabled:=true;
  766.           GroupBox2.Enabled:=true;
  767.           Label29.Enabled:=true;
  768.           Label30.Enabled:=true;
  769.           Label31.Enabled:=true;
  770.           Label32.Enabled:=true;
  771.           Label35.Enabled:=true;
  772.           Label36.Enabled:=true;
  773.           Label37.Enabled:=true;
  774.           Label38.Enabled:=true;
  775.           Label39.Enabled:=true;
  776.           Label40.Enabled:=true;
  777.           Label41.Enabled:=true;
  778.      end
  779.      else
  780.      begin
  781.           Button14.Enabled:=false;
  782.           GroupBox2.Enabled:=false;
  783.           Label29.Enabled:=false;
  784.           Label30.Enabled:=false;
  785.           Label31.Enabled:=false;
  786.           Label32.Enabled:=false;
  787.           Label35.Enabled:=false;
  788.           Label36.Enabled:=false;
  789.           Label37.Enabled:=false;
  790.           Label38.Enabled:=false;
  791.           Label39.Enabled:=false;
  792.           Label40.Enabled:=false;
  793.           Label41.Enabled:=false;
  794.      end;
  795. end;
  796.  
  797. procedure TForm1.Button14Click(Sender: TObject);
  798. var path:array[0..259] of Char;
  799.     filename:array[0..255] of Char;
  800.     fs:TFileStream;
  801. begin
  802.      GetTempPath(260,path);
  803.      GetTempFileName(path,'wav',0,filename);
  804.      fs:=TFileStream.Create(string(filename),fmCreate);
  805.      headercreate(fs,ComboBox2);
  806.      headercorrect(fs);
  807.      fs.Free;
  808.      MediaPlayer1.FileName:=string(filename);
  809.      MediaPlayer1.DeviceType:=dtWaveAudio;
  810.      MediaPlayer1.Open;
  811.      MediaPlayer1.StartRecording;
  812.      Form2.IsMP:=true;
  813.      Timer1.Enabled:=true;
  814.      with Form2 do
  815.      begin
  816.           DevID:=WAVE_MAPPER;
  817.           if Pos('Stereo',ComboBox2.Text)>0 then channel:=2 else channel:=1;
  818.           if Pos('11kHz',ComboBox2.Text)>0 then freq:=11025
  819.           else if Pos('22kHz',ComboBox2.Text)>0 then freq:=22050
  820.           else if Pos('32kHz',ComboBox2.Text)>0 then freq:=32000
  821.           else if Pos('44.1kHz',ComboBox2.Text)>0 then freq:=44100
  822.           else if Pos('48kHz',ComboBox2.Text)>0 then freq:=48000
  823.           else if Pos('5kHz',ComboBox2.Text)>0 then freq:=5000;
  824.           if Pos('8bit',ComboBox2.Text)>0 then bits:=8 else bits:=16;
  825.           ProgressBar1.Position:=0;
  826.           ShowModal;
  827.      end;
  828. end;
  829.  
  830. procedure TForm1.Timer1Timer(Sender: TObject);
  831. begin
  832.      Form2.ProgressBar1.Position:=Form2.ProgressBar1.Position+Form2.ProgressBar1.Step;
  833.      if Form2.ProgressBar1.Position=100 then
  834.      begin
  835.           Timer1.Enabled:=false;
  836.           Screen.Cursor:=crHourGlass;
  837.           Update;
  838.           Form2.ModalResult:=mrOk;
  839.           Screen.Cursor:=crDefault;
  840.      end;
  841. end;
  842.  
  843. procedure TForm1.KV1Click(Sender: TObject);
  844. begin
  845.      WinExec('sndvol32.exe',SW_SHOW);
  846. end;
  847.  
  848. // 録音開始
  849. procedure TForm1.BitBtn5Click(Sender: TObject);
  850. begin
  851.      recordingbuttonclick;
  852. end;
  853.  
  854.  
  855. procedure TForm1.recordingbuttonclick;
  856. var i:integer;
  857.  
  858. procedure createzerowaveform(filename:string;
  859.                              channel,frequency,bit:integer);
  860.                            // 大きさ0のwaveファイルを作る
  861. var fs:TFileStream;
  862.     WaveFormat1:TWAVEFORMATEX;
  863.     ck:array [0..3] of Char;
  864.     cksize:longint;
  865.  
  866. begin
  867.      fs:=TFileStream.Create(filename,fmCreate);
  868.      try
  869.      ck:='RIFF';
  870.      fs.WriteBuffer(ck,4);
  871.      cksize:=34;
  872.      fs.WriteBuffer(cksize,4);
  873.      ck:='WAVE';
  874.      fs.WriteBuffer(ck,4);
  875.      ck:='fmt ';
  876.      fs.WriteBuffer(ck,4);
  877.      ckSize:=16;
  878.      fs.WriteBuffer(cksize,4);
  879.      with waveformat1 do
  880.      begin
  881.           wFormatTag:=WAVE_FORMAT_PCM;
  882.           nChannels:=channel;
  883.           nSamplesPerSec:=frequency;
  884.           wBitsPerSample:=bit;
  885.           nAvgBytesPerSec:=frequency*channel*(bit div 8);
  886.           nBlockAlign:=channel*(bit div 8);
  887.           cbSize:=0;
  888.      end;
  889.      fs.WriteBuffer(waveformat1,18);
  890.      fs.Seek(-2,soFromCurrent);
  891.      ck:='data';
  892.      fs.WriteBuffer(ck,4);
  893.      ckSize:=0;
  894.      fs.WriteBuffer(cksize,4);
  895.      finally
  896.      fs.free;
  897.      end;
  898. end;
  899.  
  900.  
  901. // 画面を録音状態にセット
  902. procedure RecordingDisplaySetting;
  903. begin
  904.      // 他のコンポーネントの操作を禁止
  905.      BitBtn5.Enabled:=false;    // 録音ボタン
  906.      Button1.Enabled:=false;    // Waveの保存フォルダの参照
  907.      Button14.Enabled:=false;   // 今すぐ補正
  908.      SpinEdit1.Enabled:=false;  // 録音時間(hour)
  909.      SpinEdit2.Enabled:=false;  // 録音時間(min)
  910.      SpinEdit3.Enabled:=false;  // 録音時間(sec)
  911.      ComboBox2.Enabled:=false;  // 形式
  912.      CheckBox1.Enabled:=false;  // 録音後すぐに切り出す
  913.      CheckBox4.Enabled:=false;  // 0点補正
  914.      TabSheet2.Enabled:=false;  // 切り出しツール
  915.      TabSheet3.Enabled:=false;  // 結合ツール
  916.      KS1.Caption:='録音終了';   // 録音開始
  917.      KC1.Enabled:=false;        // 切り出しツールメニュー
  918.      KA1.Enabled:=false;        // 結合ツールメニュー
  919.  
  920.      BitBtn4.Enabled:=true;     // 停止ボタン
  921.  
  922.      TrackBar951.Max:=(SpinEdit1.Value*60+SpinEdit2.Value)*60+SpinEdit3.Value;
  923.      TrackBar951.Min:=0;
  924.      TrackBar951.Position:=0;
  925.      // 時刻表示のバグを直した(ver 0.8)
  926.      Label34.Caption:=FormatDateTime('hh:nn:ss',TrackBar951.Max/60/60/24);
  927.      Timer2.Enabled:=true;
  928. end;
  929.  
  930. // ファイルを録音状態にセット
  931. procedure RecordingSetting;
  932.  
  933. begin
  934.      if Edit1.Text='' then exit;
  935.      if (FileExists(Edit1.Text+'\wavkntmp.wav')) then
  936.      begin
  937.           if Application.MessageBox('テンポラリファイルがすでに存在しますが、上書きしますか?',
  938.                                     'ファイルの上書きの確認',mb_YesNo)=IDNo then Exit;
  939.      end;
  940.  
  941.      RecordingDisplaySetting;
  942.  
  943.      if Pos('Stereo',ComboBox2.Text)>0 then ch:=2 else ch:=1;
  944.      if Pos('11kHz',ComboBox2.Text)>0 then freq:=11025
  945.      else if Pos('22kHz',ComboBox2.Text)>0 then freq:=22050
  946.      else if Pos('32kHz',ComboBox2.Text)>0 then freq:=32000
  947.      else if Pos('44.1kHz',ComboBox2.Text)>0 then freq:=44100
  948.      else if Pos('48kHz',ComboBox2.Text)>0 then freq:=48000
  949.      else if Pos('5kHz',ComboBox2.Text)>0 then freq:=5000;
  950.      if Pos('8bit',ComboBox2.Text)>0 then bits:=8 else bits:=16;
  951.      createzerowaveform(Edit1.Text+'\wavkntmp.wav',ch,freq,bits);
  952. end;
  953.  
  954. begin
  955.      RecordingSetting;
  956.      MediaPlayer1.FileName:=Edit1.Text+'\wavkntmp.wav';
  957.      MediaPlayer1.Open;
  958.      MediaPlayer1.StartRecording;
  959. end;
  960.  
  961. // Waveファイルのヘッダを書く
  962. procedure TForm1.HeaderCreate(fs:TFileStream;FmtComboBox:TComboBox);
  963. var WaveFormat1:TWAVEFORMATEX;
  964.     ck:array[0..3] of Char;
  965.     cksize:longint;
  966. begin
  967.      ck:='RIFF';
  968.      fs.WriteBuffer(ck,4);
  969.      cksize:=0;
  970.      fs.WriteBuffer(cksize,4);
  971.      ck:='WAVE';
  972.      fs.WriteBuffer(ck,4);
  973.      ck:='fmt ';
  974.      fs.WriteBuffer(ck,4);
  975.      ckSize:=16;
  976.      fs.WriteBuffer(cksize,4);
  977.      with waveformat1 do
  978.      begin
  979.           if Pos('Stereo',FmtComboBox.Text)>0 then nchannels:=2 else nchannels:=1;
  980.           if Pos('11kHz',FmtComboBox.Text)>0 then nSamplesPerSec:=11025
  981.           else if Pos('22kHz',FmtComboBox.Text)>0 then nSamplesPerSec:=22050
  982.           else if Pos('32kHz',FmtComboBox.Text)>0 then nSamplesPerSec:=32000
  983.           else if Pos('44.1kHz',FmtComboBox.Text)>0 then nSamplesPerSec:=44100
  984.           else if Pos('48kHz',FmtComboBox.Text)>0 then nSamplesPerSec:=48000
  985.           else if Pos('5kHz',FmtComboBox.Text)>0 then nSamplesPerSec:=5000;
  986.           if Pos('8bit',FmtComboBox.Text)>0 then wbitsPerSample:=8 else wbitsPerSample:=16;
  987.           wFormatTag:=WAVE_FORMAT_PCM;
  988.           nAvgBytesPerSec:=nSamplesPerSec*nchannels*(wbitsPerSample div 8);
  989.           nBlockAlign:=nchannels*(wbitsPerSample div 8);
  990.           cbSize:=0;
  991.      end;
  992.      fs.WriteBuffer(waveformat1,18);
  993.      fs.Seek(-2,soFromCurrent);
  994.      ck:='data';
  995.      fs.WriteBuffer(ck,4);
  996.      ckSize:=0;
  997.      fs.WriteBuffer(cksize,4);
  998. end;
  999.  
  1000. // Waveファイルのヘッダを修正する
  1001. procedure TForm1.HeaderCorrect(fs:TFileStream);
  1002. var ckSize:longint;
  1003. begin
  1004.      fs.Seek(4,soFromBeginning);
  1005.      ckSize:=fs.Size-8;
  1006.      fs.WriteBuffer(ckSize,4);
  1007.      ckSize:=fs.Size-44;
  1008.      fs.Seek(32,soFromCurrent);
  1009.      fs.WriteBuffer(ckSize,4);
  1010. end;
  1011.  
  1012. procedure TForm1.WaveStopProc;
  1013. var k:integer;
  1014. begin
  1015.      Screen.Cursor := crHourglass;      //   砂時計型カーソルを表示します
  1016.      try
  1017.         Timer2.Enabled:=false;
  1018.         MediaPlayer1.Stop;
  1019.         MediaPlayer1.Save;
  1020.         MediaPlayer1.Close;
  1021.         // 他のコンポーネントの操作を禁止
  1022.         BitBtn5.Enabled:=true;    // 録音ボタン
  1023.         Button1.Enabled:=true;    // Waveの保存フォルダの参照
  1024.         if CheckBox4.Checked then Button14.Enabled:=true;   // 今すぐ補正
  1025.         SpinEdit1.Enabled:=true;  // 録音時間(hour)
  1026.         SpinEdit2.Enabled:=true;  // 録音時間(min)
  1027.         SpinEdit3.Enabled:=true;  // 録音時間(sec)
  1028.         ComboBox2.Enabled:=true;  // 形式
  1029.         CheckBox1.Enabled:=true;  // 録音後すぐに切り出す
  1030.         CheckBox4.Enabled:=true;  // 0点補正
  1031.         TabSheet2.Enabled:=true;  // 切り出しツール
  1032.         TabSheet3.Enabled:=true;  // 結合ツール
  1033.         KS1.Caption:='録音開始';  // 録音開始
  1034.         KC1.Enabled:=true;        // 切り出しツールメニュー
  1035.         KA1.Enabled:=true;        // 結合ツールメニュー
  1036.  
  1037.         BitBtn4.Enabled:=false;     // 停止ボタン
  1038.         TrackBar951.Position:=0;
  1039.  
  1040.      finally
  1041.             Screen.Cursor := crDefault;  //   必ず通常のカーソルに戻ります
  1042.      end;
  1043.      if CheckBox1.Checked then
  1044.      begin
  1045.           Edit3.Text:=Edit1.Text+'\wavkntmp.wav';
  1046.           if Pos('48kHz',ComboBox2.Text)>0 then k:=1
  1047.           else if Pos('44.1kHz',ComboBox2.Text)>0 then k:=2
  1048.           else if Pos('32kHz',ComboBox2.Text)>0 then k:=3
  1049.           else if Pos('22kHz',ComboBox2.Text)>0 then k:=4
  1050.           else if Pos('11kHz',ComboBox2.Text)>0 then k:=5
  1051.           else if Pos('5kHz',ComboBox2.Text)>0 then k:=6;
  1052.           if Pos('Mono',ComboBox2.Text)>0 then k:=k+6;
  1053.           if Pos('8bit',ComboBox2.Text)>0 then k:=k+12;
  1054.           ComboBox3.ItemIndex:=k-1;
  1055.           cuttingproc;
  1056.      end
  1057.      else
  1058.           Application.MessageBox('録音は正常に終了しました。',
  1059.                                  '録音終了',mb_IconInformation or mb_Ok);
  1060. end;
  1061.  
  1062. procedure TForm1.BitBtn4Click(Sender: TObject);
  1063. begin
  1064.      WaveStopProc;
  1065. end;
  1066.  
  1067. procedure TForm1.KS3Click(Sender: TObject);
  1068. begin
  1069.      cuttingproc;
  1070. end;
  1071.  
  1072. procedure TForm1.cuttingproc;
  1073. var i,ii,iii:integer;
  1074.     fs,fs2:TFileStream;
  1075.     ms:TMemoryStream;
  1076.     ckid:array[0..3] of char;
  1077.     k:integer;
  1078.     cksize:longint;
  1079.     ch,freq,bit:integer;
  1080.     bufsize:integer;
  1081.     mutesize:integer;
  1082.     trigerlevel,trigertime:integer;
  1083.     cuttime:longint;
  1084.     tracknum,loopnum2:integer;
  1085.     startpos,flag:integer;
  1086.     ls:byte;
  1087.     l:array [1..2] of smallint;
  1088.     orgpos:longint;
  1089.     zpos:array[1..2] of smallint;
  1090.     ll:longint;
  1091.     nextfile:boolean;
  1092. begin
  1093.      PageControl1.ActivePage:=TabSheet2;
  1094.      // 閾値
  1095.      trigerlevel:=SpinEdit7.Value;
  1096.      trigertime:=SpinEdit8.Value;
  1097.      // 同じ時間での切り取り
  1098.      cuttime:=(SpinEdit4.Value*60+SpinEdit5.Value)*60+SpinEdit6.Value;
  1099.  
  1100.      if Edit3.Text='' then exit;
  1101.      if (FileExists(Edit4.Text+'\wk??????.wav')) then
  1102.      begin
  1103.           if Application.MessageBox('ファイルがすでに存在しますが、上書きしますか?',
  1104.                                     'ファイルの上書きの確認',mb_YesNo)=IDNo then Exit;
  1105.      end;
  1106.  
  1107.      Form1.Enabled:=false;
  1108.      try
  1109.         if Pos('Stereo',ComboBox3.Text)>0 then ch:=2 else ch:=1;
  1110.         if Pos('11kHz',ComboBox3.Text)>0 then freq:=11025
  1111.         else if Pos('22kHz',ComboBox3.Text)>0 then freq:=22050
  1112.         else if Pos('32kHz',ComboBox3.Text)>0 then freq:=32000
  1113.         else if Pos('44.1kHz',ComboBox3.Text)>0 then freq:=44100
  1114.         else if Pos('48kHz',ComboBox3.Text)>0 then freq:=48000
  1115.         else if Pos('5kHz',ComboBox3.Text)>0 then freq:=5000;
  1116.         if Pos('8bit',ComboBox3.Text)>0 then bit:=8 else bit:=16;
  1117.         Form4.show;
  1118.         fs:=TFileStream.Create(Edit3.Text,fmOpenRead);
  1119.         try
  1120.            // waveファイルの読み取りには本来mmio関数を使うべきだが
  1121.            // これを使うと面倒なので、ここでは4バイトずつ読んで、
  1122.            // 'data'チャンクを探す
  1123.            if UpperCase(ExtractFileExt(Edit3.Text))='.WAV' then
  1124.            begin
  1125.                 fs.Seek(0,soFromBeginning);
  1126.                 k:=0;
  1127.                 ckid:='    ';
  1128.                 while not (ckid='fmt ') and (k<200) do
  1129.                 begin
  1130.                      fs.Read(ckid,4);
  1131.                      inc(k);
  1132.                 end;
  1133.                 // 200バイトも探したのに、見つからなかった(壊れてる??)
  1134.                 if k=200 then
  1135.                 begin
  1136.                      Application.MessageBox('サポートできない形式です。',
  1137.                                             'Error',mb_IconHand or mb_Ok);
  1138.                      exit;
  1139.                 end;
  1140.                 fs.Read(cksize,4);
  1141.                 k:=0;
  1142.                 ckid:='    ';
  1143.                 fs.Seek(ckSize,soFromCurrent);
  1144.                 while not (ckid='data') and (k<200) do
  1145.                 begin
  1146.                      fs.Read(ckid,4);
  1147.                      inc(k);
  1148.                 end;
  1149.                 // 200バイトも探したのに、見つからなかった(壊れてる??)
  1150.                 if k=200 then
  1151.                 begin
  1152.                      Application.MessageBox('サポートできない形式です。',
  1153.                                             'Error',mb_IconHand or mb_Ok);
  1154.                      exit;
  1155.                 end;
  1156.                 fs.Read(cksize,4);
  1157.            end
  1158.            else cksize:=fs.Size;
  1159.            orgpos:=fs.Position;
  1160.            Form4.Label1.Caption:='1曲目を生成しています';
  1161.            Application.ProcessMessages;
  1162.  
  1163. ///////////////////////////////////////////////////////////
  1164. //
  1165. //               閾値による切り出し
  1166.  
  1167.         if RadioButton1.Checked then
  1168.         begin
  1169.            // バッファサイズは8192
  1170.            bufsize:=SpinEdit8.value;//8192;
  1171.            if (CheckBox4.Checked) then
  1172.            begin
  1173.                 zpos[1]:=StrToInt(Label29.Caption);
  1174.                 zpos[2]:=StrToInt(Label30.Caption);
  1175.            end
  1176.            else
  1177.            begin
  1178.                 zpos[1]:=0;
  1179.                 zpos[2]:=0;
  1180.            end;
  1181.  
  1182.            tracknum:=1;
  1183.            mutesize:=0;
  1184.            _breakflag:=0;
  1185.            nextfile:=false;
  1186.            fs2:=TFileStream.Create(Edit4.Text+'\wk000001.wav',fmCreate);
  1187.            try
  1188.               headercreate(fs2,ComboBox3);
  1189.               ms:=TMemoryStream.Create;
  1190.               try
  1191.                  loopnum2:=ckSize div ((bit div 8)*ch*bufsize);
  1192.                  for i:=1 to loopnum2 do
  1193.                  begin
  1194.                    // バッファに読み込みます
  1195.                    ms.Clear;
  1196.                    ms.CopyFrom(fs,bufsize*ch*(bit div 8));
  1197.                    ms.Seek(0,soFromBeginning);
  1198.                    startpos:=0;
  1199.  
  1200.                    // 閾値を探す
  1201.                    flag:=0;
  1202.                    ii:=0;
  1203.                    while (flag=0) do
  1204.                    begin
  1205.                         l[2]:=0;
  1206.                         case bit of
  1207.                         8:
  1208.                         begin
  1209.                              for iii:=1 to ch do
  1210.                              begin
  1211.                                   ms.Read(ls,1);
  1212.                                   ls:=ls-zpos[iii];
  1213.                                   l[iii]:=ls-128;
  1214.                                   if (l[iii]>128) then ls:=255
  1215.                                   else if (l[iii]<-128) then ls:=0;
  1216.                                   ms.Seek(-1,soFromCurrent);
  1217.                                   ms.Write(ls,1);
  1218.                              end;
  1219.                         end;
  1220.                         16:
  1221.                         begin
  1222.                              for iii:=1 to ch do
  1223.                              begin
  1224.                                   ms.Read(l[iii],2);
  1225.                                   ll:=l[iii]-zpos[iii];
  1226.                                   if (ll>32767) then l[iii]:=32767
  1227.                                   else if (ll<-32768) then l[iii]:=-32768
  1228.                                   else l[iii]:=ll;
  1229.                                   ms.Seek(-2,soFromCurrent);
  1230.                                   ms.Write(l[iii],2);
  1231.                              end;
  1232.                         end;
  1233.                         end;
  1234.                         if (abs(l[1])<trigerlevel) and
  1235.                            (abs(l[2])<trigerlevel) then
  1236.                         begin
  1237.                            inc(mutesize);
  1238.                            if mutesize>trigertime then
  1239.                            begin
  1240.                               nextfile:=true;
  1241.                               startpos:=ii;
  1242.                            end;
  1243.                         end
  1244.                         else
  1245.                         begin
  1246.                            if nextfile then
  1247.                            begin
  1248.                                 if startpos-trigdelay>0 then startpos:=startpos-trigdelay
  1249.                                                         else startpos:=0;
  1250.                                 ms.seek(0,soFromBeginning);
  1251.                                 fs2.CopyFrom(ms,ch*(bit div 8)*startpos);
  1252.  
  1253.                                 // ファイルをクローズ
  1254.                                 headercorrect(fs2);
  1255.                                 fs2.Free;
  1256.                                 // トラック番号
  1257.                                 inc(tracknum);
  1258.                                 Form4.Label1.Caption:=Format('%d',[tracknum])+'曲目を検出しました。';
  1259.                                 Application.ProcessMessages;
  1260.  
  1261.                                 // バッファから最終的に書き込むファイル
  1262.                                 // 新しいファイルを作る
  1263.                                 fs2:=TFileStream.Create(Edit4.Text+'\wk'+Format('%6.6d',[tracknum])+'.wav',fmCreate);
  1264.                                 headercreate(fs2,ComboBox3);
  1265.                                 fs2.CopyFrom(ms,ms.Size-ms.Position);
  1266.                                 mutesize:=0;
  1267.                                 startpos:=0;
  1268.                                 flag:=1;
  1269.                                 nextfile:=false;
  1270.                            end
  1271.                         // 閾値以下の点が短すぎたら、
  1272.                         // 曲の切れ目ではないと判断
  1273.                            else
  1274.                            begin
  1275.                              mutesize:=0;
  1276.                              nextfile:=false;
  1277.                            end;
  1278.                         end;
  1279.                         inc(ii);
  1280.                         if ii=bufsize then flag:=2;
  1281.                    end;
  1282.                    if flag=2 then
  1283.                    begin
  1284.                         ms.seek(0,soFromBeginning);
  1285.                         fs2.CopyFrom(ms,ms.Size);
  1286.                    end;
  1287.                    Form4.ProgressBar1.Position:=trunc(i/loopnum2*100);
  1288.                    Application.ProcessMessages;
  1289.                    if _breakflag=-1 then exit;
  1290.                  end;
  1291.               finally
  1292.                  ms.Free;
  1293.               end;
  1294.               // 最後の残りをコピー
  1295.               fs.Seek(orgpos+loopnum2*(bit div 8)*ch*bufsize,soFromBeginning);
  1296.               ckSize:=ckSize-loopnum2*(bit div 8)*ch*bufsize;
  1297.               if ckSize<>0 then
  1298.               begin
  1299.                    for i:=0 to ckSize div ((bit div 8)*ch) do
  1300.                    begin
  1301.                         case bit of
  1302.                         8:
  1303.                         begin
  1304.                              for iii:=1 to ch do
  1305.                              begin
  1306.                                   fs.Read(ls,1);
  1307.                                   ls:=ls-zpos[iii];
  1308.                                   l[iii]:=ls-128;
  1309.                                   if (l[iii]>128) then ls:=255
  1310.                                   else if (l[iii]<-128) then ls:=0;
  1311.                                   fs2.Write(ls,1);
  1312.                              end;
  1313.                         end;
  1314.                         16:
  1315.                         begin
  1316.                              for iii:=1 to ch do
  1317.                              begin
  1318.                                   fs.Read(l[iii],2);
  1319.                                   ll:=l[iii]-zpos[iii];
  1320.                                   if (ll>32767) then l[iii]:=32767
  1321.                                   else if (ll<-32768) then l[iii]:=-32768
  1322.                                   else l[iii]:=ll;
  1323.                                   fs2.Write(l[iii],2);
  1324.                              end;
  1325.                         end;
  1326.                         end;
  1327.                    end;
  1328.               end;
  1329.               headercorrect(fs2);
  1330.            finally
  1331.               fs2.Free;
  1332.            end;
  1333.         end
  1334.  
  1335. ///////////////////////////////////////////////////////////
  1336. //
  1337. //            同じ長さのwaveに分割
  1338.  
  1339.         else
  1340.         begin
  1341.            bufsize:=cuttime*(bit div 8)*ch*freq;
  1342.            loopnum2:=cksize div bufsize;
  1343.            _breakflag:=0;
  1344.            for i:=1 to loopnum2 do
  1345.            begin
  1346.                 Form4.Label1.Caption:=Format('%d',[i])+'曲目の生成中です。';
  1347.                 Application.ProcessMessages;
  1348.                 fs2:=TFileStream.Create(Edit4.Text+'\wk'+Format('%6.6d',[i])+'.wav',fmCreate);
  1349.                 try
  1350.                    headercreate(fs2,ComboBox3);
  1351.                    fs2.CopyFrom(fs,bufsize);
  1352.                    headercorrect(fs2);
  1353.                 finally
  1354.                    fs2.Free;
  1355.                 end;
  1356.                 Form4.ProgressBar1.Position:=trunc(i/loopnum2*100);
  1357.                 Application.ProcessMessages;
  1358.                 if _breakflag=-1 then exit;
  1359.            end;
  1360.            fs2:=TFileStream.Create(Edit4.Text+'\wk'+Format('%6.6d',[loopnum2+1])+'.wav',fmCreate);
  1361.            try
  1362.               headercreate(fs2,ComboBox3);
  1363.               fs2.CopyFrom(fs,cksize-loopnum2*bufsize);
  1364.               headercorrect(fs2);
  1365.            finally
  1366.               fs2.Free;
  1367.            end;
  1368.         end;
  1369.         finally
  1370.            fs.Free;
  1371.            Form4.Label1.Caption:='';
  1372.            Form4.Hide;
  1373.         end;
  1374.         Form1.Enabled:=true;
  1375.         Application.MessageBox('切り出しは正常に終了しました。',
  1376.                                '切り出し終了',mb_IconInformation or mb_Ok);
  1377.         // 結合前のファイルを消去
  1378.         if CheckBox6.Checked then
  1379.         begin
  1380.            if DeleteFile(Edit3.Text) then
  1381.               Edit3.Text:='';
  1382.         end;
  1383.      finally
  1384.         Form1.Enabled:=true;
  1385.      end;
  1386. end;
  1387.  
  1388. procedure TForm1.Timer2Timer(Sender: TObject);
  1389. begin
  1390.      TrackBar951.Position:=TrackBar951.Position+1;
  1391.      // 時刻表示のバグを直した(ver 0.7)
  1392.      Label33.Caption:=FormatDateTime('hh:nn:ss',TrackBar951.Position/60/60/24);
  1393.      if TrackBar951.Position=TrackBar951.Max then
  1394.      begin
  1395.           Timer2.Enabled:=false;
  1396.           wavestopproc;
  1397.      end;
  1398. end;
  1399.  
  1400. procedure TForm1.Button10Click(Sender: TObject);
  1401. var i:integer;
  1402.     fs,fs2:TFileStream;
  1403.     ckid:array[0..3] of char;
  1404.     k:integer;
  1405.     cksize:longint;
  1406. begin
  1407.      if ListBox1.Items.Count=0 then exit;
  1408.      if Edit2.Text='' then Exit;
  1409.      Form1.Enabled:=false;
  1410.      try
  1411.         Form3.Show;
  1412.         _breakflag:=0;
  1413.         fs:=TFileStream.Create(Edit2.Text,fmCreate);
  1414.         try
  1415.            headercreate(fs,ComboBox4);
  1416.            for i:=0 to ListBox1.Items.Count-1 do
  1417.            begin
  1418.                 Form3.Label1.Caption:=ListBox1.Items[i]+'を結合しています...';
  1419.                 Application.ProcessMessages;
  1420.                 fs2:=TFileStream.Create(ListBox1.Items[i],fmOpenRead);
  1421.                 try
  1422.                    // waveファイルの読み取りには本来mmio関数を使うべきだが
  1423.                    // これを使うと面倒なので、ここでは4バイトずつ読んで、
  1424.                    // 'data'チャンクを探す
  1425.                    if UpperCase(ExtractFileExt(ListBox1.Items[i]))='.WAV' then
  1426.                    begin
  1427.                       fs2.Seek(0,soFromBeginning);
  1428.                       k:=0;
  1429.                       ckid:='    ';
  1430.                       while not (ckid='fmt ') and (k<200) do
  1431.                       begin
  1432.                            fs2.Read(ckid,4);
  1433.                            inc(k);
  1434.                       end;
  1435.                       // 200バイトも探したのに、見つからなかった(壊れてる??)
  1436.                       if k=200 then
  1437.                       begin
  1438.                            Application.MessageBox('サポートできない形式です。',
  1439.                                                   'Error',mb_IconHand or mb_Ok);
  1440.                            exit;
  1441.                       end;
  1442.                       fs2.Read(cksize,4);
  1443.                       k:=0;
  1444.                       ckid:='    ';
  1445.                       fs2.Seek(ckSize,soFromCurrent);
  1446.                       while not (ckid='data') and (k<200) do
  1447.                       begin
  1448.                            fs2.Read(ckid,4);
  1449.                            inc(k);
  1450.                       end;
  1451.                       // 200バイトも探したのに、見つからなかった(壊れてる??)
  1452.                       if k=200 then
  1453.                       begin
  1454.                            Application.MessageBox('サポートできない形式です。',
  1455.                                                   'Error',mb_IconHand or mb_Ok);
  1456.                            exit;
  1457.                       end;
  1458.                       fs2.Read(cksize,4);
  1459.                    end
  1460.                    else cksize:=fs2.Size;
  1461.                    fs.CopyFrom(fs2,cksize);
  1462.                    Application.ProcessMessages;
  1463.                    if _breakflag=-1 then exit;
  1464.                 finally
  1465.                    fs2.Free;
  1466.                 end;
  1467.                 // 結合前のファイルを消去
  1468.                 if CheckBox5.Checked then
  1469.                      DeleteFile(ListBox1.Items[i]);
  1470.                 Form3.ProgressBar1.Position:=trunc((i+1)/ListBox1.Items.Count*100);
  1471.            end;
  1472.            headercorrect(fs);
  1473.         finally
  1474.            fs.Free;
  1475.            Form3.Label1.Caption:='';
  1476.            Form3.Hide;
  1477.         end;
  1478.         Form1.Enabled:=true;
  1479.         Application.MessageBox('結合は正常に終了しました。',
  1480.                                '結合終了',mb_Ok);
  1481.         if CheckBox5.Checked then
  1482.            ListBox1.Items.Clear;
  1483.      finally
  1484.         Form1.Enabled:=true;
  1485.      end;
  1486. end;
  1487.  
  1488. procedure TForm1.SpinEdit5Change(Sender: TObject);
  1489. begin
  1490.      if (SpinEdit4.Value=0) and
  1491.         (SpinEdit5.Value=0) then
  1492.      begin
  1493.           SpinEdit6.Value:=1;
  1494.           SpinEdit6.MinValue:=1;
  1495.           SpinEdit6.MaxValue:=59;
  1496.      end
  1497.      else
  1498.      begin
  1499.           SpinEdit6.MinValue:=0;
  1500.           SpinEdit6.MaxValue:=59;
  1501.      end;
  1502. end;
  1503.  
  1504. procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  1505. begin
  1506.      // 録音中であった
  1507.      if BitBtn4.Enabled then
  1508.      begin
  1509.           if Application.MessageBox('録音を中断して終了しますか?',
  1510.                                     '録音中',mb_IconWarning or mb_YesNo)=IDYes then
  1511.           begin
  1512.                CheckBox1.Checked:=false;
  1513.                WaveStopProc;
  1514.           end
  1515.           else CanClose:=false;
  1516.      end;
  1517. end;
  1518.  
  1519. // エクスプローラからのDrag&Dropを許可する
  1520. procedure TForm1.CreateParams(var Params: TCreateParams);
  1521. begin
  1522.   inherited CreateParams(Params);
  1523.   Params.ExStyle := Params.EXStyle or WS_EX_ACCEPTFILES;
  1524. end;
  1525.  
  1526. // エクスプローラからのDrag&Drop
  1527. procedure TForm1.WMDropFiles(var msg: TWMDROPFILES);
  1528. var m:integer;
  1529.     buf:array[0..260] of Char;
  1530.     i:integer;
  1531.     s:string;
  1532.     StringList1:TStringList;
  1533. begin
  1534.   msg.Result := 0;
  1535.   if PageControl1.ActivePage=TabSheet2 then
  1536.   begin
  1537.        DragQueryFile(msg.Drop, 0, buf, 260);
  1538.        s:=string(buf);
  1539.        if (UpperCase(ExtractFileExt(s))='.RAW') or
  1540.           (UpperCase(ExtractFileExt(s))='.WAV') then
  1541.           SetCutFileName(s);
  1542.   end
  1543.   else if PageControl1.ActivePage=TabSheet3 then
  1544.   begin
  1545.        // Drag&Dropされたファイルの数
  1546.        m:=DragQueryFile(msg.Drop, Cardinal(-1), NIL, 0);
  1547.        StringList1:=TStringList.Create;
  1548.        try
  1549.           for i:=0 to m-1 do
  1550.           begin
  1551.                // i番目のファイル名
  1552.                DragQueryFile(msg.Drop, i, buf, 260);
  1553.                s:=string(buf);
  1554.                if (UpperCase(ExtractFileExt(s))='.RAW') or
  1555.                   (UpperCase(ExtractFileExt(s))='.WAV') then
  1556.                begin
  1557.                   StringList1.Add(s);
  1558.                end;
  1559.           end;
  1560.           if StringList1.Count>0 then SetCmbFiles(StringList1);
  1561.        finally
  1562.           StringList1.Free;
  1563.        end;
  1564.   end;
  1565. end;
  1566.  
  1567. procedure TForm1.KS1Click(Sender: TObject);
  1568. begin
  1569.      if KS1.Caption='録音開始(&S)' then
  1570.            recordingbuttonclick
  1571.      else  WaveStopProc;
  1572. end;
  1573.  
  1574. procedure TForm1.CheckBox1Click(Sender: TObject);
  1575. begin
  1576.      DiskFreeCalcProc;
  1577. end;
  1578.  
  1579. procedure TForm1.CDPlayerC1Click(Sender: TObject);
  1580. begin
  1581.      WinExec('cdplayer.exe',SW_SHOW);
  1582. end;
  1583.  
  1584. procedure TForm1.SpeedButton1Click(Sender: TObject);
  1585. begin
  1586.      Label29.Caption:='0';
  1587.      Label30.Caption:='0';
  1588.      Fzeroadjdata[1]:=0;
  1589.      Fzeroadjdata[2]:=0;
  1590. end;
  1591.  
  1592. procedure TForm1.SpeedButton2Click(Sender: TObject);
  1593. begin
  1594.      Label37.Caption:='0';
  1595.      Label38.Caption:='0';
  1596. end;
  1597.  
  1598. procedure TForm1.SpeedButton3Click(Sender: TObject);
  1599. begin
  1600.      Label40.Caption:='0';
  1601.      Label41.Caption:='0';
  1602. end;
  1603.  
  1604. function TForm1.Getzeroadjdata(i:integer):integer;
  1605. begin
  1606.      Result:=Fzeroadjdata[i];
  1607. end;
  1608.  
  1609. procedure TForm1.Setzeroadjdata(i,value:integer);
  1610. begin
  1611.      Fzeroadjdata[i]:=value;
  1612. end;
  1613.  
  1614. procedure TForm1.ComboBox2Change(Sender: TObject);
  1615. var i, oldCB3Index : integer;
  1616. begin
  1617.    oldCB3Index := ComboBox3.ItemIndex;
  1618.    i := 0;
  1619.    ComboBox3.ItemIndex := i;
  1620.    while (i<ComboBox3.Items.Count) and
  1621.          (ComboBox2.Items[ComboBox2.ItemIndex] <> ComboBox3.Items[ComboBox3.ItemIndex]) do
  1622.    begin
  1623.       ComboBox3.ItemIndex := i;
  1624.       inc(i);
  1625.    end;
  1626.    if i = ComboBox3.Items.Count then
  1627.       ComboBox3.ItemIndex := oldCB3Index;
  1628.    DiskFreeCalcProc;
  1629. end;
  1630.  
  1631. end.
  1632.