From 3e561cd4fd1eb46590cb70aaf940f7775a855966 Mon Sep 17 00:00:00 2001 From: brunzelchen Date: Tue, 21 Dec 2010 17:51:42 +0000 Subject: added pitch detection for editor git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/1.0.1 Challenge MOD@2765 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UMain.pas | 24 +++---- Game/Code/Classes/UMusic.pas | 8 +++ Game/Code/Classes/URecord.pas | 18 +++++- Game/Code/Screens/UScreenEditSub.pas | 118 ++++++++++++++++++++++++++++++++++- 4 files changed, 153 insertions(+), 15 deletions(-) diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index e1205cd8..bc3ac1b0 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -605,17 +605,17 @@ begin Czesci[P].Czesc[S].Nuta[Pet].Dlugosc > BRange) then begin // przesuwanie tonu w odpowiednia game => shifting tone in the corresponding game? - while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton > 6) do - Sound[CP].Ton := Sound[CP].Ton - 12; - while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton < -6) do - Sound[CP].Ton := Sound[CP].Ton + 12; + while (Sound[CP].TonGamy - Czesci[P].Czesc[S].Nuta[Pet].Ton > 6) do + Sound[CP].TonGamy := Sound[CP].TonGamy - 12; + while (Sound[CP].TonGamy - Czesci[P].Czesc[S].Nuta[Pet].Ton < -6) do + Sound[CP].TonGamy := Sound[CP].TonGamy + 12; // Half size Notes Patch NoteHit := false; - AktTon := Sound[CP].Ton; + AktTon := Sound[CP].TonGamy; Range := 2 - Ini.Difficulty; - if (abs(Czesci[P].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range) or + if (abs(Czesci[P].Czesc[S].Nuta[Pet].Ton - Sound[CP].TonGamy) <= Range) or DEBUG_NOTE_HIT then begin AktTon := Czesci[P].Czesc[S].Nuta[Pet].Ton; @@ -784,17 +784,17 @@ begin Czesci[P].Czesc[S].Nuta[Pet].Dlugosc > BRange) then begin // przesuwanie tonu w odpowiednia game - while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton > 6) do - Sound[CP].Ton := Sound[CP].Ton - 12; - while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton < -6) do - Sound[CP].Ton := Sound[CP].Ton + 12; + while (Sound[CP].TonGamy - Czesci[P].Czesc[S].Nuta[Pet].Ton > 6) do + Sound[CP].TonGamy := Sound[CP].TonGamy - 12; + while (Sound[CP].TonGamy - Czesci[P].Czesc[S].Nuta[Pet].Ton < -6) do + Sound[CP].TonGamy := Sound[CP].TonGamy + 12; // Half size Notes Patch NoteHit := false; - AktTon := Sound[CP].Ton; + AktTon := Sound[CP].TonGamy; Range := 2 - Ini.Difficulty; - if (abs(Czesci[P].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range) or + if (abs(Czesci[P].Czesc[S].Nuta[Pet].Ton - Sound[CP].TonGamy) <= Range) or DEBUG_NOTE_HIT then begin AktTon := Czesci[P].Czesc[S].Nuta[Pet].Ton; diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index d192927e..1ce421b8 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -60,6 +60,7 @@ type Loaded: boolean; Loop: boolean; + CaptureStarted: boolean; // DXSound: TDXSound; // Player: TcmxMp3; DSP_VocalRemover: HDSP; @@ -415,6 +416,7 @@ var S: integer; begin + CaptureStarted := false; if RecordSystem = 1 then begin SetLength(Sound, 6 {max players});//Ini.Players+1); for S := 0 to High(Sound) do begin //Ini.Players do begin @@ -771,6 +773,9 @@ var P1: integer; P2: integer; begin + if CaptureStarted then + Exit; + for S := 0 to High(Sound) do Sound[S].BufferLong[0].Clear; @@ -785,6 +790,8 @@ begin if (P1 > 0) or (P2 > 0) then CaptureCard(SC); end; + + CaptureStarted := true; end; procedure TMusic.CaptureStop; @@ -800,6 +807,7 @@ begin if P2 > PlayersPlay then P2 := 0; if (P1 > 0) or (P2 > 0) then StopCard(SC); end; + CaptureStarted := false; end; //procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); diff --git a/Game/Code/Classes/URecord.pas b/Game/Code/Classes/URecord.pas index 7354d931..57919fe1 100644 --- a/Game/Code/Classes/URecord.pas +++ b/Game/Code/Classes/URecord.pas @@ -27,6 +27,7 @@ type procedure AnalizujBufor; // use to analyze sound from buffers to get new pitch procedure AnalizujByAutocorrelation; // we call it to analyze sound by checking Autocorrelation function AnalyzeAutocorrelationFreq(Freq: real): real; // use this to check one frequency by Autocorrelation + function GetToneString: string; //from usdx 1.1 end; TSoundCardInput = record @@ -61,9 +62,24 @@ var Poz: integer; Recording: TRecord; +const + // from usdx 1.1 + ToneStrings: array[0..11] of string = ( + 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B' + ); + implementation uses UMain, ULog; +// from usdx 1.1 +function TSound.GetToneString: string; +begin + if (SzczytJest) then + Result := ToneStrings[TonGamy] + IntToStr(Ton div 12 + 2) + else + Result := '-'; +end; + procedure TSound.ProcessNewBuffer; var S: integer; @@ -153,7 +169,7 @@ begin if MaxV >= Threshold then begin // found acceptable volume // 0.1 SzczytJest := true; TonGamy := MaxT mod 12; - Ton := MaxT mod 12; + Ton := MaxT; end; // Log.LogAnalyze('--> Weight: ') diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas index 02817d51..be058408 100644 --- a/Game/Code/Screens/UScreenEditSub.pas +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -2,7 +2,14 @@ unit UScreenEditSub; interface -uses UMenu, UVideo, TextGL, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, UMenuText, +uses + UMenu, + UVideo, + TextGL, + UMusic, + URecord, + SDL, + SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, UMenuText, ULyrics, Math, gl, UThemes, MidiOut, UHelp; type @@ -82,6 +89,9 @@ type StartTry: boolean; PlayTime: real; + ActTonePitch: integer; + + procedure DrawPitch(x, y, Width, Height: single); procedure StartVideo; procedure StartVideoPreview; procedure NewBeat; @@ -135,6 +145,7 @@ type const ID='ID_001'; //for help system + NumHalftones = 36; implementation uses UGraphic, UDraw, UMain, USkins, ULanguage; @@ -626,6 +637,12 @@ begin end; end; + SDLK_N: + begin + // Set actual note over pitch detection + Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[0]].Ton := ActTonePitch; + end; + SDLK_C: begin // Capitalize letter at the beginning of line @@ -1440,6 +1457,99 @@ begin end; end; +procedure TScreenEditSub.DrawPitch(x, y, Width, Height: single); +var + x1, y1, x2, y2: single; + i: integer; + ToneBoxWidth: real; + ToneString: string; + ToneStringWidth, ToneStringHeight: real; + ToneStringMaxWidth: real; + ToneStringCenterXOffset: real; + +const + PitchBarInnerHSpacing = 2; + PitchBarInnerVSpacing = 1; + +begin + // calc tone pitch + Sound[0].AnalizujBufor; + + // coordinates for black rect + x1 := x; + y1 := y; + x2 := x + Width; + y2 := y + Height; + + // init blend mode + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + // draw black background-rect + glColor4f(0, 0, 0, 0.8); + glBegin(GL_QUADS); + glVertex2f(x1, y1); + glVertex2f(x2, y1); + glVertex2f(x2, y2); + glVertex2f(x1, y2); + glEnd(); + + // coordinates for tone boxes + ToneBoxWidth := Width / NumHalftones; + y1 := y1 + PitchBarInnerVSpacing; + y2 := y2 - PitchBarInnerVSpacing; + + glBegin(GL_QUADS); + // draw tone boxes + for i := 0 to NumHalftones-1 do + begin + x1 := x + i * ToneBoxWidth + PitchBarInnerHSpacing; + x2 := x1 + ToneBoxWidth - 2*PitchBarInnerHSpacing; + + if ((Sound[0].SzczytJest) and + (Sound[0].Ton = i)) then + begin + // highlight current tone-pitch + glColor3f(1, i / (NumHalftones-1), 0); + ActTonePitch := i; + end + else + begin + // grey other tone-pitches + glColor3f(0.3, i / (NumHalftones-1) * 0.3, 0); + end; + + glVertex2f(x1, y1); + glVertex2f(x2, y1); + glVertex2f(x2, y2); + glVertex2f(x1, y2); + end; + glEnd(); + + glDisable(GL_BLEND); + + /// + // draw the name of the tone + /////// + + ToneString := Sound[0].GetToneString + '(' + IntToStr(ActTonePitch) + ')'; + ToneStringHeight := 8; + + SetFontSize(ToneStringHeight); + + // center + // Note: for centering let us assume that G#4 has the max. horizontal extent + ToneStringWidth := glTextWidth(PChar(ToneString)); + ToneStringMaxWidth := glTextWidth('G#4 (222)'); + ToneStringCenterXOffset := (ToneStringMaxWidth-ToneStringWidth) / 2; + + // draw + SetFontPos(x-ToneStringWidth-ToneStringCenterXOffset, y-ToneStringHeight/2); + glColor3f(0, 0, 0); + glPrint(PChar(ToneString)); +end; + + procedure TScreenEditSub.StartVideo; var R: real; @@ -2539,6 +2649,7 @@ begin end else begin + Music.CaptureStart; Refresh; MidiOut := TMidiOutput.Create(nil); MidiOut.Open; @@ -3045,7 +3156,6 @@ begin glEnd; glDisable(GL_BLEND); end; - if UVideo.VideoOpened and PlayVideo then begin @@ -3093,7 +3203,10 @@ begin end; end; end else + begin + DrawPitch(400, 75, 390, 15); StartVideoPreview; + end; end; procedure TScreenEditSub.DrawStatics; @@ -3450,6 +3563,7 @@ procedure TScreenEditSub.onHide; begin MidiOut.Close; MidiOut.Free; + Music.CaptureStop; end; function TScreenEditSub.GetNoteName(Note: Integer): String; -- cgit v1.2.3