2017년 2월 5일 일요일

MS의 SpVoice를 임포트하여 글 읽어 주기를 구현했네요.

목소리가 별로 네요... 예전에 구글 API 이용 했었는데 그걸로 돌아 갈까....
음성을 선택 할 수 있는데 별반 차이가 없네요.

procedure TfrmStudyLaw2.FormCreate(Sender: TObject);
var
FileName: String;
SOTokenVoice: ISpeechObjectToken;
SOTokenVoices: ISpeechObjectTokens;
....
begin
// speech
SpVoice1.EventInterests:= SVEAllEvents;
SOTokenVoices:= SpVoice1.GetVoices('','');
for i := 0 to SOTokenVoices.Count-1 do begin
SOTokenVoice:= SOTokenVoices.Item(i);
ComboBoxVoices.Items.AddObject(SOTokenVoice.GetDescription(0), TObject(SOTokenVoice));
SOTokenVoice._AddRef;
end;
if ComboBoxVoices.Items.Count > 0 then begin
ComboBoxVoices.ItemIndex := ComboBoxVoices.Items.IndexOf(SpVoice1.Voice.GetDescription(0))
end;
end.


procedure TfrmStudyLaw2.Button5Click(Sender: TObject);
const iSpeechFlags: integer = SVSFlagsAsync + SVSFPurgeBeforeSpeak + SVSFIsXML;
var
idx, jdx, kdx: Integer;
begin
SpVoice1.Rate:= tbRate.Position;
for idx := 0 to SpinEdit1.Value-1 do begin
if CBStopSpeechA.Checked then Break;
for jdx := 0 to ListBox1.Items.Count-1 do begin
if CBStopSpeechA.Checked then Break;
if ListBox1.Checked[jdx] then
for kdx := 0 to SpinEdit2.Value-1 do begin
if CBStopSpeech1.Checked then Break;
SpVoice1.Speak(ListBox1.Items[jdx],iSpeechFlags);
repeat
Application.ProcessMessages;
until (SpVoice1.WaitUntilDone(10));
end;
CBStopSpeech1.Checked:= False;
end;
end;
CBStopSpeechA.Checked:= False;
end;

트랙바를 이용하여 mp3 구간 옮기기 트랙바에 MouseDown 이벤트 없어서

트랙바를 이용하여 mp3 구간 옮기기 트랙바에 MouseDown 이벤트 없어서

TTrackBar = class(Vcl.ComCtrls.TTrackbar)
  protected
    property OnMouseUp;
    property OnMouseDown;
  end;
  .....
    procedure CheckListBox1ClickCheck(Sender: TObject);
    procedure CheckListBox1Click(Sender: TObject);


procedure TForm1.TBMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Timer1.Enabled:= False;
BASS_ChannelPause(iStream);
end;

procedure TForm1.TBMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
BASS_ChannelSetPosition(iStream, TrackBar2.Position,0);
BASS_ChannelPlay(iStream,False);
Timer1.Enabled:= True;
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
StatusBar1.SimpleText:= '지연시간(100mSec) : '+ IntToStr(TrackBar1.Position);
end;

Bass.dll 을 이용한 mp3 연속 플레이하기

폼생성시 초기화 합니다.
mp3 파일은 sqlite 파일로 되어 있어 CheckListBox로 필요한 것만 읽어 옮니다.
트랙바 부분은 아래에 설명

procedure TForm1.FormCreate(Sender: TObject);
var istr: string;
begin
TrackBar2.OnMouseUp := TBMouseUp;
TrackBar2.OnMouseDown := TBMouseDown;
ZConnection1.Connect;
ZTable1.Open;
// check the correct BASS was loaded
if (HIWORD(BASS_GetVersion) <> BASSVERSION) then begin
MessageBox(0,'An incorrect version',nil,MB_ICONERROR);
Halt;
end;
iPause:= False;
// Initialize audio - default device, 44100hz, stereo, 16 bits
if not BASS_Init(-1, 44100, 0, Handle, nil) then
Error('Error initializing audio!');
end;

시작버튼

procedure TForm1.btPlayClick(Sender: TObject);
var
iCoor: TPoint;
begin
Timer1.Enabled:= False;
iPause:= False;
btRestart.Caption:= 'Pause';
BASS_ChannelStop(iStream);
if CheckListBox1.items.Count = 0 then exit;
// Play the stream (continuing from current position)
if CheckListBox1.ItemIndex >= 0 then begin
iCount:= 0;
playmp3(CheckListBox1.ItemIndex);
TrackBar2.Max:= BASS_ChannelGetLength(iStream, BASS_POS_BYTE);
Timer1.Enabled:= True;
end;
btDate.Caption:= DBEdit2.Text;
end;

Bass Stream 을 생성(파일 경로로); istream: integer로 전역 선언

procedure TForm1.playmp3(idx: integer);
var f: PChar;
begin
if CheckListBox1.checked[idx]= True then exit;

f:= PChar(CheckListBox1.items[idx]);
iStream:= BASS_StreamCreateFile(False, f, 0, 0, 0 or BASS_UNICODE);
//BASS_ChannelSetAttribute(iStream, BASS_ATTRIB_PAN, (Random(201) - 100) / 100);
//BASS_ChannelSetAttribute(iStream, BASS_ATTRIB_VOL, 0.8);
if not BASS_ChannelPlay(iStream, True) then Error('Error playing stream!');
end;

타이머가 돌아가면서 하나의 mp3 가 끝났는지 확인하고 반복하고나 다음 mp3 연주

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if BASS_GetCPU < 0.00001 then begin
inc(iCount);
if iCount >= spinedit1.Value then begin
iCount:= 0;
CheckListBox1.ItemIndex:= CheckListBox1.ItemIndex + 1;
CheckListBox1.Tag:= CheckListBox1.Tag + 1;
ZQuery1.Next;
if CheckListBox1.Tag <> CheckListBox1.ItemIndex then begin
CheckListBox1.ItemIndex:= 0;
CheckListBox1.Tag:= 0;
iCount:= 0;
Zquery1.First;
Timer1.Enabled:= False;
end else
//
end;
Timer1.Enabled:= False;
if CheckListBox1.Checked[CheckListBox1.ItemIndex]= False then
Delay(TrackBar1.Position*100);
playmp3(CheckListBox1.ItemIndex);
TrackBar2.Max:= BASS_ChannelGetLength(iStream, BASS_POS_BYTE);
Timer1.Enabled:= True;
end;
TrackBar2.Position := BASS_ChannelGetPosition(iStream, BASS_POS_BYTE);
end;

델파이 12.1이냐 11.3이냐?

 델파이가 12.1이 나왔습니다. 혹시 11.3버전의 커뮤니티버전이 필요하시는분이 있을 수 있을 것 같아 https://altd.embarcadero.com/.../RADStudio_11_3_esd_28... 와 이것 찾느랴 엄청고생함.