diff --git a/Output/Languages/German.xml b/Output/Languages/German.xml index 0b1e172a..52cbba63 100644 --- a/Output/Languages/German.xml +++ b/Output/Languages/German.xml @@ -1,4 +1,4 @@ - + Deutsch Vocaluxe und diff --git a/Output/Languages/Hungarian.xml b/Output/Languages/Hungarian.xml new file mode 100644 index 00000000..d384338f --- /dev/null +++ b/Output/Languages/Hungarian.xml @@ -0,0 +1,239 @@ + + + + Magyar + + + + Vocaluxe + és + + Kilépés + Mentés + Vissza + Kiválasztás + + Audio streams + Video streams + Textures + ToneAbs + Max Volume + Loaded songs + Mouse + + Normál + Duett + Dalrészlet + Rövid verzió + + Aranyhangú + Szupersztár + Tehetséges Énekes + Kezdő Énekes + Reményteljes + Fejlődőképes + Amatőr + Botfülű + + + Szoftveres + OpenGL + Direct3D + + Legalacsonyabb + Alacsony + Közepes + Magas + Legmagasabb + + Ki + Be + + Only FPS + Level 1 + Level 2 + Level 3 + Max + + Lista + Körhinta + Csempe + Könyv + + Amikor Szükséges + Indulásnál + Dinamikusan + + Nincs + Véletlenszerű + Könyvtár + Előadó + Előadó Betűrendben + Cím Betűrendben + Kiadás + Műfaj + Év + Évtized + Nyelv + + Könnyű + Normál + Nehéz + + Jelenlegi + Hátralévő + Összes + + Normál + Kibővített + + Saját és Háttérzene + Nincs Saját Zene + Csak Saját zene + + Mindent + Csak Nevek és Profilképek + Semmit + + + Betöltés + Összes + Dalok + betöltve + + Főmenü + Éneklés + Buli + Beállítások + Profilok + + Parti Mód Választás + Parti Mód + Leírás + Készítő + Verzió + Nem Betölthető Parti Mód. + Célközönség + Csapatok Nélkül + Csapatok Száma + Játékosok Száma + + Játékos Választás + Játékos + Játékos 1 + Játékos 2 + Játékos 3 + Játékos 4 + Játékos 5 + Játékos 6 + Figyelem: Nincs mikrofon csatlakoztatva a következő játékoshoz %v! + Figyelem: Nincsenek mikrofonok csatlakoztatva a következő játékosokhoz %v! + Figyelem: Nincs profil hozzárendelve a következő játékoshoz %v! + Figyelem: Nincsenek profilok hozzárendelve a következő játékosokhoz %v! + + Dalválasztás + Éneklés + Listához Hozzáadás + Bezárás + Véletlenszerű Dal Kiválasztása + Véletlenszerű Kategória Kiválasztása + Összes Dal Éneklése + Itt látható Dalok Éneklése + Lista Megnyitása + Véletlenszerű Dalrészlet Éneklése + Dalrészletek Éneklése + Új Lista + Dalbeállítások + Keresés: + Nincs Nyelv + Nincs Év + Nincs Műfaj + Nincs Kiadás + Minden Dal + (%v Dal) + (%v Dal) + + Szünet + Befejezés + Folytatás + Dal Kihagyása + + Pontszámok + Értékelés + Pont + Nehézség + Összpontszám + + Eredménylista + + Profilok + Játékos Neve + Nehézségi Szint + Profilkép + Vendég Profil + Jelenlegi + Új + Törlés + Pillanatkép Készítése + Pillanatkép Mentése + Pillanatkép Törlése + Webkamera + + Menü Beállítások + Játék + Hang + Mikrofon + Kép + Dalszöveg + Téma + + Játék Beállítások + Nyelv + Debug Level + Dal Menü + Dalok Rendezése + Rendezés + Játék Nehézsége + Idő Mutatás + + Mikrofon Beállítások + Eszköz + Bemenet + Csatorna 1 + Csatorna 2 + Mikrofon Késleltetés + Figyelem: Egy játékos két mikrofont használ. + Késleltetés Tesztelése + + Hang Beállítások + Háttérzene + Háttérzene Hangereje + Háttérzene Forrása + Előnézeti Zene Hangereje + Zene Hangereje + + Téma Beállítások + Téma + Kinézet + Borító Téma + Kotta Mutatása + Hangmagasság Segítő Mutatása + Idősáv Nézete + Játékos Infó Halványan + Borító Betöltés + + Dalszöveg Beállítások + Stílus + Dalszöveg Felül + + Képi Beállítások + Animált Háttér + Videó Előnézet + Videó Éneklés Közben + Jelenlegi Háttérzene Videó Mutatása + Webkamerák + Webkamera Tulajdonságok + + Hangerő + + diff --git a/Output/PartyModes/Challenge/Languages/German.xml b/Output/PartyModes/Challenge/Languages/German.xml index 1cf41f93..71e41a5b 100644 --- a/Output/PartyModes/Challenge/Languages/German.xml +++ b/Output/PartyModes/Challenge/Languages/German.xml @@ -1,4 +1,4 @@ - + Deutsch Challenge Modus Spiele einen Wettkampfmodus diff --git a/Output/PartyModes/Challenge/Languages/Hungarian.xml b/Output/PartyModes/Challenge/Languages/Hungarian.xml new file mode 100644 index 00000000..fa2a2376 --- /dev/null +++ b/Output/PartyModes/Challenge/Languages/Hungarian.xml @@ -0,0 +1,37 @@ + + + + Magyar + + + + Bajnokság Mód + Bajnokság Módban egymás ellen + Azoknak akik szeretnék megmérettetni magukat egymás ellen + Következő + Vissza + Kezdés + Kilépés + Igen + Nem + Következő Kör + + Bajnokság Mód: Beállítások + Játékosok Száma + Mikrofonok Száma + Körök Száma + + Bajnokság Mód: Válassz Játékost + + Bajnokság Mód: Áttekintés + Poz + Név + Körök + Győzelmek + Énekpontok + Pontszám + Biztos hogy ki akarsz lépni? + Következik: + Véget ért a verseny, a győztes pedig... + + diff --git a/Output/PartyModes/ChallengeMedley/Languages/German.xml b/Output/PartyModes/ChallengeMedley/Languages/German.xml index a5efe812..6dfdf04f 100644 --- a/Output/PartyModes/ChallengeMedley/Languages/German.xml +++ b/Output/PartyModes/ChallengeMedley/Languages/German.xml @@ -1,4 +1,4 @@ - + Deutsch Challenge Medley Modus Spiele einen Wettkampfmodus nur mit 5er Medleys diff --git a/Output/PartyModes/ChallengeMedley/Languages/Hungarian.xml b/Output/PartyModes/ChallengeMedley/Languages/Hungarian.xml new file mode 100644 index 00000000..bca3bac5 --- /dev/null +++ b/Output/PartyModes/ChallengeMedley/Languages/Hungarian.xml @@ -0,0 +1,37 @@ + + + + Magyar + + + + Bajnokság Egyveleg Mód + Bajnokság mód 5 vagy több dalrészletet énekelve + Azoknak akik egymás ellen szeretnének játszani és csak dalrészleteket énekelni. + Következő + Vissza + Kezdés + Kilépés + Igen + Nem + Következő Kör + + Bajnokság Egyveleg Mód: Beállítások + Játékosok Száma + Mikrofonok Száma + Körök Száma + + Bajnokság Egyveleg Mód: Válassz Játékost + + Bajnokság Egyveleg Mód: Áttekintés + Poz + Név + Körök + Győzelmek + Énekpontok + Pontszám + Biztos hogy ki akarsz lépni? + Következik: + Véget ért a verseny, a győztes... + + diff --git a/Output/PartyModes/TicTacToe/Languages/German.xml b/Output/PartyModes/TicTacToe/Languages/German.xml index d4a350a2..c743cc43 100644 --- a/Output/PartyModes/TicTacToe/Languages/German.xml +++ b/Output/PartyModes/TicTacToe/Languages/German.xml @@ -1,4 +1,4 @@ - + Deutsch Tic-Tac-Toe diff --git a/Output/PartyModes/TicTacToe/Languages/Hungarian.xml b/Output/PartyModes/TicTacToe/Languages/Hungarian.xml new file mode 100644 index 00000000..b0627563 --- /dev/null +++ b/Output/PartyModes/TicTacToe/Languages/Hungarian.xml @@ -0,0 +1,42 @@ + + + + Magyar + + + + Tic-Tac-Toe + Tic-Tac-Toe egy kicsit másképp + Vicces versenymód egy kis stratégiával, szerencsével és ügyességel + Következő + Vissza + Kezdés + Kilépés + Igen + Nem + Kezdés + Dalok + Csapat + Dal Lista + Kategória + Összes Dal + + Tic-Tac-Toe: Beállítások + 1. Csapat játékosainak száma + 2. Csapat játékosainak száma + Mezők száma + Dal-forrás + Játék Mód + + Tic-Tac-Toe: Válassz Játékost + 1. Csapat + 2. Csapat + + Tic-Tac-Toe + Válassz egy mezőt. + Következő Játékos + Biztos hogy ki akarsz lépni? + És a győztes... + Nem volt győztesünk ebben a körben... + + diff --git a/Output/x64/acinerella.dll b/Output/x64/acinerella.dll index c57d9661..06abee8d 100644 Binary files a/Output/x64/acinerella.dll and b/Output/x64/acinerella.dll differ diff --git a/Output/x64/avcodec-54.dll b/Output/x64/avcodec-54.dll index 3906d3bf..b677a13a 100644 Binary files a/Output/x64/avcodec-54.dll and b/Output/x64/avcodec-54.dll differ diff --git a/Output/x64/avformat-54.dll b/Output/x64/avformat-54.dll index 9b9f360f..115949e2 100644 Binary files a/Output/x64/avformat-54.dll and b/Output/x64/avformat-54.dll differ diff --git a/Output/x64/avutil-52.dll b/Output/x64/avutil-52.dll index 025a4bf1..d8aa1179 100644 Binary files a/Output/x64/avutil-52.dll and b/Output/x64/avutil-52.dll differ diff --git a/Output/x64/swresample-0.dll b/Output/x64/swresample-0.dll index 026fe92d..ad600fdb 100644 Binary files a/Output/x64/swresample-0.dll and b/Output/x64/swresample-0.dll differ diff --git a/Output/x64/swscale-2.dll b/Output/x64/swscale-2.dll index 2b915705..58cf9119 100644 Binary files a/Output/x64/swscale-2.dll and b/Output/x64/swscale-2.dll differ diff --git a/Output/x86/acinerella.dll b/Output/x86/acinerella.dll index e4dc5ce2..e83b3f64 100644 Binary files a/Output/x86/acinerella.dll and b/Output/x86/acinerella.dll differ diff --git a/Output/x86/avcodec-54.dll b/Output/x86/avcodec-54.dll index d6e72cb7..62616e37 100644 Binary files a/Output/x86/avcodec-54.dll and b/Output/x86/avcodec-54.dll differ diff --git a/Output/x86/avformat-54.dll b/Output/x86/avformat-54.dll index d1233b57..68d8c5d4 100644 Binary files a/Output/x86/avformat-54.dll and b/Output/x86/avformat-54.dll differ diff --git a/Output/x86/avutil-52.dll b/Output/x86/avutil-52.dll index 98791159..12ab8847 100644 Binary files a/Output/x86/avutil-52.dll and b/Output/x86/avutil-52.dll differ diff --git a/Output/x86/swresample-0.dll b/Output/x86/swresample-0.dll index e546c3c7..2b52c0f4 100644 Binary files a/Output/x86/swresample-0.dll and b/Output/x86/swresample-0.dll differ diff --git a/Output/x86/swscale-2.dll b/Output/x86/swscale-2.dll index 200ebf30..e7b7dd3d 100644 Binary files a/Output/x86/swscale-2.dll and b/Output/x86/swscale-2.dll differ diff --git a/PartyModes/PartyModeTicTacToe/PartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/PartyModeTicTacToe.cs index 22c3b57e..cedebdf7 100644 --- a/PartyModes/PartyModeTicTacToe/PartyModeTicTacToe.cs +++ b/PartyModes/PartyModeTicTacToe/PartyModeTicTacToe.cs @@ -62,6 +62,8 @@ namespace Vocaluxe.PartyModes public List Songs; public List ProfileIDsTeam1; public List ProfileIDsTeam2; + public List PlayerTeam1; + public List PlayerTeam2; public int[] NumJokerRandom; public int[] NumJokerRetry; } @@ -96,6 +98,8 @@ namespace Vocaluxe.PartyModes { public bool FadeToSinging; public bool FadeToNameSelection; + public List PlayerTeam1; + public List PlayerTeam2; public List Rounds; public int SingRoundNr; public List Songs; @@ -128,6 +132,8 @@ namespace Vocaluxe.PartyModes public int Team; public List ProfileIDsTeam1; public List ProfileIDsTeam2; + public List PlayerTeam1; + public List PlayerTeam2; public ESongSource SongSource; public int CategoryID; @@ -176,6 +182,8 @@ namespace Vocaluxe.PartyModes GameData.NumPlayerTeam2 = 2; GameData.ProfileIDsTeam1 = new List(); GameData.ProfileIDsTeam2 = new List(); + GameData.PlayerTeam1 = new List(); + GameData.PlayerTeam2 = new List(); GameData.CurrentRoundNr = 0; GameData.SingRoundNr = 0; GameData.SongSource = ESongSource.TR_ALLSONGS; @@ -202,8 +210,12 @@ namespace Vocaluxe.PartyModes ToScreenMain.Rounds = new List(); ToScreenMain.Songs = new List(); + ToScreenMain.PlayerTeam1 = new List(); + ToScreenMain.PlayerTeam2 = new List(); GameData.Songs = new List(); GameData.Rounds = new List(); + GameData.PlayerTeam1 = new List(); + GameData.PlayerTeam2 = new List(); return true; } @@ -269,6 +281,8 @@ namespace Vocaluxe.PartyModes GameData.Rounds = data.ScreenMain.Rounds; GameData.SingRoundNr = data.ScreenMain.SingRoundNr; GameData.Songs = data.ScreenMain.Songs; + GameData.PlayerTeam1 = data.ScreenMain.PlayerTeam1; + GameData.PlayerTeam2 = data.ScreenMain.PlayerTeam2; } if (data.ScreenMain.FadeToNameSelection) { @@ -351,10 +365,13 @@ namespace Vocaluxe.PartyModes ToScreenMain.ProfileIDsTeam1 = GameData.ProfileIDsTeam1; ToScreenMain.ProfileIDsTeam2 = GameData.ProfileIDsTeam2; CreateRounds(); - PrepareSongList(); SetNumJokers(); + PreparePlayerList(0); + PrepareSongList(); ToScreenMain.Rounds = GameData.Rounds; ToScreenMain.Songs = GameData.Songs; + ToScreenMain.PlayerTeam1 = GameData.PlayerTeam1; + ToScreenMain.PlayerTeam1 = GameData.PlayerTeam2; ToScreenMain.NumJokerRandom = GameData.NumJokerRandom; ToScreenMain.NumJokerRetry = GameData.NumJokerRetry; ToScreenMain.Team = GameData.Team; @@ -372,6 +389,8 @@ namespace Vocaluxe.PartyModes GameData.Team = 0; else GameData.Team = 1; + UpdateSongList(); + UpdatePlayerList(); ToScreenMain.CurrentRoundNr = GameData.CurrentRoundNr; ToScreenMain.NumPlayerTeam1 = GameData.NumPlayerTeam1; ToScreenMain.NumPlayerTeam2 = GameData.NumPlayerTeam2; @@ -380,6 +399,8 @@ namespace Vocaluxe.PartyModes ToScreenMain.ProfileIDsTeam2 = GameData.ProfileIDsTeam2; ToScreenMain.Rounds = GameData.Rounds; ToScreenMain.Songs = GameData.Songs; + ToScreenMain.PlayerTeam1 = GameData.PlayerTeam1; + ToScreenMain.PlayerTeam2 = GameData.PlayerTeam2; ToScreenMain.NumJokerRandom = GameData.NumJokerRandom; ToScreenMain.NumJokerRetry = GameData.NumJokerRetry; ToScreenMain.Team = GameData.Team; @@ -490,51 +511,102 @@ namespace Vocaluxe.PartyModes private void CreateRounds() { GameData.Rounds = new List(); - //Prepare Player-IDs - List Team1 = new List(); - List Team2 = new List(); - List IDs1 = new List(); - List IDs2 = new List(); - int num = 0; - int random = 0; - //Add IDs to team-list - while (Team1.Count < GameData.NumFields) - { - if (IDs1.Count == 0) - for (int i = 0; i < GameData.NumPlayerTeam1; i++) - IDs1.Add(i); - if (IDs2.Count == 0) - for (int i = 0; i < GameData.NumPlayerTeam2; i++) - IDs2.Add(i); - if (Team1.Count < GameData.NumFields) - { - random = _Base.Game.GetRandom((IDs1.Count - 1) * 10); - num = (int)Math.Round((double)random/10); - if (num >= IDs1.Count) - num = IDs1.Count - 1; - Team1.Add(IDs1[num]); - IDs1.Remove(Team1[Team1.Count - 1]); - } - if (Team2.Count < GameData.NumFields) - { - random = _Base.Game.GetRandom((IDs2.Count - 1) * 20); - num = (int)Math.Round((double)random / 20); - if (num >= IDs2.Count) - num = IDs2.Count - 1; - Team2.Add(IDs2[num]); - IDs2.Remove(Team2[Team2.Count - 1]); - } - } - for (int i = 0; i < GameData.NumFields; i++) { Round r = new Round(); - r.SingerTeam1 = Team1[i]; - r.SingerTeam2 = Team2[i]; GameData.Rounds.Add(r); } } + private void PreparePlayerList(int Team) + { + if (Team == 0) + { + GameData.PlayerTeam1 = new List(); + GameData.PlayerTeam2 = new List(); + + //Prepare Player-IDs + List IDs1 = new List(); + List IDs2 = new List(); + int num = 0; + int random = 0; + //Add IDs to team-list + while (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0] && IDs1.Count == 0 && GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1] && IDs2.Count == 0) + { + if (IDs1.Count == 0) + for (int i = 0; i < GameData.NumPlayerTeam1; i++) + IDs1.Add(i); + if (IDs2.Count == 0) + for (int i = 0; i < GameData.NumPlayerTeam2; i++) + IDs2.Add(i); + if (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0]) + { + random = _Base.Game.GetRandom((IDs1.Count - 1) * 10); + num = (int)Math.Round((double)random / 10); + if (num >= IDs1.Count) + num = IDs1.Count - 1; + GameData.PlayerTeam1.Add(IDs1[num]); + IDs1.RemoveAt(num); + } + if (GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1]) + { + random = _Base.Game.GetRandom((IDs2.Count - 1) * 20); + num = (int)Math.Round((double)random / 20); + if (num >= IDs2.Count) + num = IDs2.Count - 1; + GameData.PlayerTeam2.Add(IDs2[num]); + IDs2.RemoveAt(num); + } + } + } + else if (Team == 1) + { + //Prepare Player-IDs + List IDs = new List(); + int num = 0; + int random = 0; + //Add IDs to team-list + while (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0] && IDs.Count == 0) + { + if (IDs.Count == 0) + for (int i = 0; i < GameData.NumPlayerTeam1; i++) + IDs.Add(i); + if (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0]) + { + random = _Base.Game.GetRandom((IDs.Count - 1) * 10); + num = (int)Math.Round((double)random / 10); + if (num >= IDs.Count) + num = IDs.Count - 1; + GameData.PlayerTeam1.Add(IDs[num]); + IDs.RemoveAt(num); + } + } + } + else if (Team == 2) + { + //Prepare Player-IDs + List IDs = new List(); + int num = 0; + int random = 0; + //Add IDs to team-list + while (GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1] && IDs.Count == 0) + { + if (IDs.Count == 0) + for (int i = 0; i < GameData.NumPlayerTeam2; i++) + IDs.Add(i); + if (GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1]) + { + random = _Base.Game.GetRandom((IDs.Count - 1) * 20); + num = (int)Math.Round((double)random / 20); + if (num >= IDs.Count) + num = IDs.Count - 1; + GameData.PlayerTeam2.Add(IDs[num]); + IDs.RemoveAt(num); + } + } + } + } + private void PrepareSongList() { EGameMode gm = EGameMode.TR_GAMEMODE_NORMAL; @@ -596,6 +668,20 @@ namespace Vocaluxe.PartyModes } } + private void UpdatePlayerList() + { + if (GameData.PlayerTeam1.Count == 0) + PreparePlayerList(1); + if (GameData.PlayerTeam2.Count == 0) + PreparePlayerList(2); + } + + private void UpdateSongList() + { + if (GameData.Songs.Count == 0) + PrepareSongList(); + } + private void StartRound(int RoundNr) { _Base.Game.Reset(); @@ -612,6 +698,7 @@ namespace Vocaluxe.PartyModes SProfile[] profiles = _Base.Profiles.GetProfiles(); Round r = GameData.Rounds[RoundNr]; + bool isDuet = _Base.Songs.GetSongByID(player[0].SongID).IsDuet; for (int i = 0; i < 2; i++) { @@ -629,7 +716,7 @@ namespace Vocaluxe.PartyModes player[0].Name = profiles[GameData.ProfileIDsTeam1[r.SingerTeam1]].PlayerName; player[0].Difficulty = profiles[GameData.ProfileIDsTeam1[r.SingerTeam1]].Difficulty; player[0].ProfileID = GameData.ProfileIDsTeam1[r.SingerTeam1]; - if (GameData.GameMode == EPartyGameMode.TR_GAMEMODE_DUET) + if (isDuet) player[0].LineNr = 0; } if (GameData.ProfileIDsTeam2[r.SingerTeam2] < profiles.Length) @@ -637,7 +724,7 @@ namespace Vocaluxe.PartyModes player[1].Name = profiles[GameData.ProfileIDsTeam2[r.SingerTeam2]].PlayerName; player[1].Difficulty = profiles[GameData.ProfileIDsTeam2[r.SingerTeam2]].Difficulty; player[1].ProfileID = GameData.ProfileIDsTeam2[r.SingerTeam2]; - if (GameData.GameMode == EPartyGameMode.TR_GAMEMODE_DUET) + if (isDuet) player[1].LineNr = 1; } SongSelected(r.SongID); diff --git a/PartyModes/PartyModeTicTacToe/PartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/PartyScreenTicTacToeMain.cs index 1f37e910..19bcd9e0 100644 --- a/PartyModes/PartyModeTicTacToe/PartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/PartyScreenTicTacToeMain.cs @@ -67,7 +67,7 @@ namespace Vocaluxe.PartyModes private int OldSelectedField = -1; private int[,] Possibilities; - private EStatus Action; + private EStatus Status; public PartyScreenTicTacToeMain() { @@ -89,6 +89,8 @@ namespace Vocaluxe.PartyModes config.SingRoundNr = 1; config.Rounds = new List(); config.Songs = new List(); + config.PlayerTeam1 = new List(); + config.PlayerTeam2 = new List(); config.FadeToNameSelection = false; config.FadeToSinging = false; Data.ScreenMain = config; @@ -135,8 +137,10 @@ namespace Vocaluxe.PartyModes case Keys.Back: case Keys.Escape: if (!ExitPopupVisible) - if (GameData.CurrentRoundNr == 1 && Action != EStatus.FieldSelected) + if (GameData.CurrentRoundNr == 1 && Status != EStatus.FieldSelected) Back(); + else if(Status == EStatus.None) + EndParty(); else ShowPopup(true); else @@ -148,13 +152,15 @@ namespace Vocaluxe.PartyModes { if (Buttons[htButtons(ButtonNextRound)].Selected) NextRound(); - if (Buttons[htButtons(ButtonBack)].Selected && GameData.CurrentRoundNr == 1 && Action != EStatus.FieldSelected) + if (Buttons[htButtons(ButtonBack)].Selected && GameData.CurrentRoundNr == 1 && Status != EStatus.FieldSelected) Back(); - if (Buttons[htButtons(ButtonExit)].Selected && (GameData.CurrentRoundNr > 1 || Action == EStatus.FieldSelected)) + if (Buttons[htButtons(ButtonExit)].Selected && (GameData.CurrentRoundNr > 1 || Status == EStatus.FieldSelected) && Status != EStatus.None) ShowPopup(true); + else if (Status == EStatus.None) + EndParty(); for (int i = 0; i < GameData.NumFields; i++) { - switch (Action) + switch (Status) { case EStatus.FieldChoosing: if (Fields[i].Button.Selected) @@ -173,7 +179,7 @@ namespace Vocaluxe.PartyModes break; } } - if (Action == EStatus.FieldSelected) + if (Status == EStatus.FieldSelected) { if (Buttons[htButtons(ButtonJokerRandomT1)].Selected) UseJoker(0, 0); @@ -211,10 +217,13 @@ namespace Vocaluxe.PartyModes if (Buttons[htButtons(ButtonBack)].Selected) Back(); if (Buttons[htButtons(ButtonExit)].Selected) - ShowPopup(true); + if (Status == EStatus.None) + EndParty(); + else + ShowPopup(true); for (int i = 0; i < GameData.NumFields; i++) { - switch (Action) + switch (Status) { case EStatus.FieldChoosing: if (Fields[i].Button.Selected) @@ -233,7 +242,7 @@ namespace Vocaluxe.PartyModes break; } } - if(Action == EStatus.FieldSelected) + if(Status == EStatus.FieldSelected) { if (Buttons[htButtons(ButtonJokerRandomT1)].Selected) UseJoker(0, 0); @@ -258,8 +267,10 @@ namespace Vocaluxe.PartyModes if (MouseEvent.RB) { if (!ExitPopupVisible) - if (GameData.CurrentRoundNr == 1 && Action != EStatus.FieldSelected) + if (GameData.CurrentRoundNr == 1 && Status != EStatus.FieldSelected) Back(); + else if(Status == EStatus.None) + EndParty(); else ShowPopup(true); else @@ -291,10 +302,15 @@ namespace Vocaluxe.PartyModes Buttons[htButtons(ButtonBack)].Visible = false; Buttons[htButtons(ButtonExit)].Visible = true; } + + Status = EStatus.FieldChoosing; + + UpdateFields(); + UpdateFieldContents(); + int Winner = GetWinner(); if (GameData.CurrentRoundNr <= GameData.NumFields && Winner == 0) { - Action = EStatus.FieldChoosing; UpdateTeamChoosingMessage(); Texts[htTexts(TextNextPlayerT1)].Visible = false; Texts[htTexts(TextNextPlayerT2)].Visible = false; @@ -312,9 +328,10 @@ namespace Vocaluxe.PartyModes } else { - Action = EStatus.None; + Status = EStatus.None; Buttons[htButtons(ButtonNextRound)].Visible = false; Texts[htTexts(TextFinishMessage)].Visible = true; + Texts[htTexts(TextTeamChoosing)].Visible = false; if (Winner > 0) { Texts[htTexts(TextFinishMessage)].Color = _Base.Theme.GetPlayerColor(Winner); @@ -328,9 +345,6 @@ namespace Vocaluxe.PartyModes SetInteractionToButton(Buttons[htButtons(ButtonExit)]); } - UpdateFields(); - UpdateFieldContents(); - ShowPopup(false); } @@ -425,23 +439,23 @@ namespace Vocaluxe.PartyModes Fields[i].Button.Color = _Base.Theme.GetPlayerColor(Fields[i].Content.Winner); Fields[i].Button.SColor = _Base.Theme.GetPlayerColor(Fields[i].Content.Winner); } - if (Action == EStatus.FieldSelected && SelectedField == i) + if (Status == EStatus.FieldSelected && SelectedField == i) { Fields[i].Button.Texture = _Base.Songs.GetSongByID(Fields[i].Content.SongID).CoverTextureBig; Fields[i].Button.Color = new SColorF(1, 1, 1, 1); Fields[i].Button.SColor = new SColorF(1, 1, 1, 1); Fields[i].Button.Enabled = false; } - if (Action == EStatus.JokerRetry && Fields[i].Content.Finished) + if (Status == EStatus.JokerRetry && Fields[i].Content.Finished) { Fields[i].Button.SColor = _Base.Theme.GetPlayerColor(GameData.Team+1); Fields[i].Button.Enabled = true; } - if (Action == EStatus.JokerRetry && !Fields[i].Content.Finished) + if (Status == EStatus.JokerRetry && !Fields[i].Content.Finished) { Fields[i].Button.Enabled = false; } - if(Action == EStatus.FieldSelected) + if(Status == EStatus.FieldSelected) { Fields[i].Button.Enabled = false; } @@ -451,11 +465,24 @@ namespace Vocaluxe.PartyModes private void FieldSelected() { int SongID = 0; + int SingerTeam1 = 0; + int SingerTeam2 = 0; if (GameData.Songs.Count > 0) { SongID = GameData.Songs[0]; GameData.Songs.RemoveAt(0); } + if (GameData.PlayerTeam1.Count > 0) + { + SingerTeam1 = GameData.PlayerTeam1[0]; + GameData.PlayerTeam1.RemoveAt(0); + } + + if (GameData.PlayerTeam2.Count > 0) + { + SingerTeam2 = GameData.PlayerTeam2[0]; + GameData.PlayerTeam2.RemoveAt(0); + } Menu.SongMenu.CSong Song = _Base.Songs.GetSongByID(SongID); _Base.BackgroundMusic.SetStatus(true); @@ -465,9 +492,11 @@ namespace Vocaluxe.PartyModes _Base.Sound.SetStreamVolume(PreviewStream, 0f); _Base.Sound.Play(PreviewStream); _Base.Sound.Fade(PreviewStream, _Base.Config.GetBackgroundMusicVolume(), 1f); - Action = EStatus.FieldSelected; + Status = EStatus.FieldSelected; Fields[SelectedField].Content.SongID = SongID; GameData.Rounds[SelectedField].SongID = SongID; + GameData.Rounds[SelectedField].SingerTeam1 = SingerTeam1; + GameData.Rounds[SelectedField].SingerTeam2 = SingerTeam2; UpdateFieldContents(); Texts[htTexts(TextNextPlayerT1)].Visible = true; @@ -500,7 +529,7 @@ namespace Vocaluxe.PartyModes _Base.Sound.SetStreamVolume(PreviewStream, 0f); _Base.Sound.Play(PreviewStream); _Base.Sound.Fade(PreviewStream, _Base.Config.GetBackgroundMusicVolume(), 1f); - Action = EStatus.FieldSelected; + Status = EStatus.FieldSelected; Fields[SelectedField].Content.SongID = SongID; GameData.Rounds[SelectedField].SongID = SongID; GameData.Rounds[SelectedField].SingerTeam1 = GameData.Rounds[OldSelectedField].SingerTeam1; @@ -549,7 +578,7 @@ namespace Vocaluxe.PartyModes GameData.Team = TeamNr; if (!_Base.Sound.IsFinished(PreviewStream)) _Base.Sound.FadeAndStop(PreviewStream, 0, 1); - Action = EStatus.JokerRetry; + Status = EStatus.JokerRetry; OldSelectedField = SelectedField; SelectedField = -1; UpdateFieldContents(); @@ -563,7 +592,7 @@ namespace Vocaluxe.PartyModes { Texts[htTexts(TextTeamChoosing)].Color = _Base.Theme.GetPlayerColor(GameData.Team + 1); Texts[htTexts(TextTeamChoosing)].Text = _Base.Language.Translate("TR_TEAM", _PartyModeID) + " " + (GameData.Team + 1) + "! " + _Base.Language.Translate("TR_SCREENMAIN_TEAM_CHOOSE", _PartyModeID); - if (Action == EStatus.JokerRetry || Action == EStatus.FieldChoosing) + if (Status == EStatus.JokerRetry || Status == EStatus.FieldChoosing) Texts[htTexts(TextTeamChoosing)].Visible = true; else Texts[htTexts(TextTeamChoosing)].Visible = false; @@ -575,10 +604,14 @@ namespace Vocaluxe.PartyModes Buttons[htButtons(ButtonJokerRandomT2)].Visible = true; Buttons[htButtons(ButtonJokerRandomT1)].Text.Text = GameData.NumJokerRandom[0].ToString(); Buttons[htButtons(ButtonJokerRandomT2)].Text.Text = GameData.NumJokerRandom[1].ToString(); + Buttons[htButtons(ButtonJokerRandomT1)].Enabled = GameData.NumJokerRandom[0] > 0; + Buttons[htButtons(ButtonJokerRandomT2)].Enabled = GameData.NumJokerRandom[1] > 0; Buttons[htButtons(ButtonJokerRetryT1)].Visible = true; Buttons[htButtons(ButtonJokerRetryT2)].Visible = true; Buttons[htButtons(ButtonJokerRetryT1)].Text.Text = GameData.NumJokerRetry[0].ToString(); Buttons[htButtons(ButtonJokerRetryT2)].Text.Text = GameData.NumJokerRetry[1].ToString(); + Buttons[htButtons(ButtonJokerRetryT1)].Enabled = GameData.NumJokerRetry[0] > 0; + Buttons[htButtons(ButtonJokerRetryT2)].Enabled = GameData.NumJokerRetry[1] > 0; } private void NextRound() @@ -589,6 +622,8 @@ namespace Vocaluxe.PartyModes Data.ScreenMain.FadeToSinging = true; Data.ScreenMain.Songs = GameData.Songs; Data.ScreenMain.SingRoundNr = SelectedField; + Data.ScreenMain.PlayerTeam1 = GameData.PlayerTeam1; + Data.ScreenMain.PlayerTeam2 = GameData.PlayerTeam2; _PartyMode.DataFromScreen(_ThemeName, Data); } diff --git a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs index 1d4fd1bf..9eb62509 100644 --- a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs +++ b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs @@ -388,7 +388,9 @@ namespace Vocaluxe.Lib.Sound const long BEGINREFILL = 800000L; private CSyncTimer _SyncTimer; - private bool _Initialized; + private static bool _Initialized = false; + private static int _NumStreams = 0; + private static Object _Mutex = new object(); private int _ByteCount = 4; private float _Volume = 1f; private float _VolumeMax = 1f; @@ -403,8 +405,8 @@ namespace Vocaluxe.Lib.Sound private bool _fading = false; - private PortAudio.PaHostApiInfo _apiInfo; - private PortAudio.PaDeviceInfo _outputDeviceInfo; + private static PortAudio.PaHostApiInfo _apiInfo; + private static PortAudio.PaDeviceInfo _outputDeviceInfo; private IntPtr _Ptr = new IntPtr(0); private Stopwatch _FadeTimer = new Stopwatch(); @@ -446,7 +448,6 @@ namespace Vocaluxe.Lib.Sound public PortAudioStream() { - _Initialized = false; _SyncTimer = new CSyncTimer(0f, 1f, 0.02f); _DecoderThread = new Thread(Execute); } @@ -578,12 +579,18 @@ namespace Vocaluxe.Lib.Sound { Paused = false; _pauseStreamAfterFade = false; - errorCheck("StartStream", PortAudio.Pa_StartStream(_Ptr)); + lock (_Mutex) + { + errorCheck("StartStream", PortAudio.Pa_StartStream(_Ptr)); + } } public void Stop() { - errorCheck("StartStream", PortAudio.Pa_StopStream(_Ptr)); + lock (_Mutex) + { + errorCheck("StopStream (playback)", PortAudio.Pa_StopStream(_Ptr)); + } Skip(0f); } @@ -609,17 +616,23 @@ namespace Vocaluxe.Lib.Sound try { - if (errorCheck("Initialize", PortAudio.Pa_Initialize())) - return -1; + lock (_Mutex) + { + if (!_Initialized) + { + if (errorCheck("Initialize", PortAudio.Pa_Initialize())) + return -1; + _Initialized = true; - _Initialized = true; - int hostApi = apiSelect(); - _apiInfo = PortAudio.Pa_GetHostApiInfo(hostApi); - _outputDeviceInfo = PortAudio.Pa_GetDeviceInfo(_apiInfo.defaultOutputDevice); - _paStreamCallback = new PortAudio.PaStreamCallbackDelegate(_PaStreamCallback); + int hostApi = apiSelect(); + _apiInfo = PortAudio.Pa_GetHostApiInfo(hostApi); + _outputDeviceInfo = PortAudio.Pa_GetDeviceInfo(_apiInfo.defaultOutputDevice); + if (_outputDeviceInfo.defaultLowOutputLatency < 0.1) + _outputDeviceInfo.defaultLowOutputLatency = 0.1; + } + } - if (_outputDeviceInfo.defaultLowOutputLatency < 0.1) - _outputDeviceInfo.defaultLowOutputLatency = 0.1; + _paStreamCallback = new PortAudio.PaStreamCallbackDelegate(_PaStreamCallback); } catch (Exception) @@ -634,6 +647,9 @@ namespace Vocaluxe.Lib.Sound _Duration = _Decoder.GetLength(); FormatInfo format = _Decoder.GetFormatInfo(); + if (format.SamplesPerSecond == 0) + return -1; + _ByteCount = 2 * format.ChannelCount; _BytesPerSecond = format.SamplesPerSecond * _ByteCount; _CurrentTime = 0f; @@ -650,20 +666,24 @@ namespace Vocaluxe.Lib.Sound outputParams.suggestedLatency = _outputDeviceInfo.defaultLowOutputLatency; uint bufsize = (uint)CConfig.AudioBufferSize; - errorCheck("OpenDefaultStream (playback)", PortAudio.Pa_OpenStream( - out _Ptr, - IntPtr.Zero, - ref outputParams, - format.SamplesPerSecond, - bufsize, - PortAudio.PaStreamFlags.paNoFlag, - _paStreamCallback, - data)); + lock (_Mutex) + { + errorCheck("OpenDefaultStream (playback)", PortAudio.Pa_OpenStream( + out _Ptr, + IntPtr.Zero, + ref outputParams, + format.SamplesPerSecond, + bufsize, + PortAudio.PaStreamFlags.paNoFlag, + _paStreamCallback, + data)); + } stream.handle = _Ptr.ToInt32(); if (stream.handle != 0) { + _NumStreams++; _Paused = true; _waiting = true; _FileOpened = true; @@ -808,7 +828,15 @@ namespace Vocaluxe.Lib.Sound if (_Initialized) { Stop(); - PortAudio.Pa_Terminate(); + _NumStreams--; + if (_NumStreams == 0) + { + lock (_Mutex) + { + PortAudio.Pa_Terminate(); + _Initialized = false; + } + } } _Closeproc(_StreamID); diff --git a/Vocaluxe/Lib/Sound/CPortAudioRecord.cs b/Vocaluxe/Lib/Sound/CPortAudioRecord.cs index dd4a631b..2df903f7 100644 --- a/Vocaluxe/Lib/Sound/CPortAudioRecord.cs +++ b/Vocaluxe/Lib/Sound/CPortAudioRecord.cs @@ -119,6 +119,16 @@ namespace Vocaluxe.Lib.Sound _Buffer[i].Reset(); } + for (int i = 0; i < _recHandle.Length; i++) + { + int waitcount = 0; + while (waitcount < 5 && PortAudio.Pa_IsStreamStopped(_recHandle[i]) == PortAudio.PaError.paStreamIsNotStopped) + { + System.Threading.Thread.Sleep(1); + waitcount++; + } + } + for (int i = 0; i < _recHandle.Length; i++) { _recHandle[i] = IntPtr.Zero; diff --git a/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs b/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs index 6afcafe2..d6830b94 100644 --- a/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs +++ b/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs @@ -27,8 +27,8 @@ namespace Vocaluxe.Lib.Sound.Decoder public override void Init() { - _rc = new TAc_read_callback(read_proc); - _sc = new TAc_seek_callback(seek_proc); + //_rc = new TAc_read_callback(read_proc); + //_sc = new TAc_seek_callback(seek_proc); _FileOpened = false; @@ -41,63 +41,51 @@ namespace Vocaluxe.Lib.Sound.Decoder return; _FileName = FileName; - _fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read); + //_fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read); _instance = CAcinerella.ac_init(); - CAcinerella.ac_open(_instance, IntPtr.Zero, null, _rc, _sc, null, IntPtr.Zero); - - _Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance)); - - if (!_Instance.opened) + int ret = 0; + //CAcinerella.ac_open(_instance, IntPtr.Zero, null, _rc, _sc, null, IntPtr.Zero); + if ((ret = CAcinerella.ac_open2(_instance, _FileName)) < 0) { - //Free(); + CLog.LogError("Error opening sound file (Errorcode: " + ret.ToString() + "): " + _FileName); return; } - int AudioStreamIndex = -1; + _Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance)); - TAc_stream_info Info = new TAc_stream_info(); - for (int i = 0; i < _Instance.stream_count; i++) + if (!_Instance.opened || _Instance.info.duration == 0) { - CAcinerella.ac_get_stream_info(_instance, i, out Info); - - if (Info.stream_type == TAc_stream_type.AC_STREAM_TYPE_AUDIO) - { - try - { - _audiodecoder = CAcinerella.ac_create_decoder(_instance, i); - } - catch (Exception) - { - return; - } - - AudioStreamIndex = i; - break; - } + if (!_Instance.opened) + CLog.LogError("Can't open sound file: " + _FileName); + else + CLog.LogError("Can't open sound file (length = 0?): " + _FileName); + return; } - if (AudioStreamIndex < 0) + try { - //Free(); + _audiodecoder = CAcinerella.ac_create_audio_decoder(_instance); + } + catch (Exception e) + { + CLog.LogError("Can't create audio decoder for file: " + _FileName + "; " + e.Message); + return; + } + + if (_audiodecoder == IntPtr.Zero) + { + CLog.LogError("Can't create audio decoder for file: " + _FileName); return; } TAc_decoder Audiodecoder = (TAc_decoder)Marshal.PtrToStructure(_audiodecoder, typeof(TAc_decoder)); - _FormatInfo = new FormatInfo(); - _FormatInfo.SamplesPerSecond = Audiodecoder.stream_info.audio_info.samples_per_second; _FormatInfo.BitDepth = Audiodecoder.stream_info.audio_info.bit_depth; _FormatInfo.ChannelCount = Audiodecoder.stream_info.audio_info.channel_count; _CurrentTime = 0f; - - if (_FormatInfo.BitDepth != 16) - { - CLog.LogError("Unsupported BitDepth in file " + FileName); - return; - } _FileOpened = true; } @@ -136,7 +124,7 @@ namespace Vocaluxe.Lib.Sound.Decoder if (!_Initialized && !_FileOpened) return 0f; - return (float)_Instance.info.duration / 1000f; ; + return (float)_Instance.info.duration / 1000f; } public override void SetPosition(float Time) diff --git a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs index 0b3fbc90..54d90fe3 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs @@ -253,6 +253,17 @@ namespace Vocaluxe.Lib.Video.Acinerella return _ac_open(PAc_instance, sender, open_proc, read_proc, seek_proc, close_proc, proberesult); } } + + [DllImport(AcDll, EntryPoint = "ac_open2", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] + private static extern Int32 _ac_open2(IntPtr PAc_instance, [MarshalAs(UnmanagedType.LPStr)]string Filename); + + public static Int32 ac_open2(IntPtr PAc_instance, string Filename) + { + lock (_lock) + { + return _ac_open2(PAc_instance, Filename); + } + } // Closes an opened media file. //procedure ac_close(inst: PAc_instance);cdecl; external ac_dll; @@ -316,6 +327,28 @@ namespace Vocaluxe.Lib.Video.Acinerella return _ac_create_decoder(PAc_instance, nb); } } + + [DllImport(AcDll, EntryPoint = "ac_create_audio_decoder", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] + private static extern IntPtr _ac_create_audio_decoder(IntPtr PAc_instance); + + public static IntPtr ac_create_audio_decoder(IntPtr PAc_instance) + { + lock (_lock) + { + return _ac_create_audio_decoder(PAc_instance); + } + } + + [DllImport(AcDll, EntryPoint = "ac_create_video_decoder", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] + private static extern IntPtr _ac_create_video_decoder(IntPtr PAc_instance); + + public static IntPtr ac_create_video_decoder(IntPtr PAc_instance) + { + lock (_lock) + { + return _ac_create_video_decoder(PAc_instance); + } + } // Frees an created decoder. //procedure ac_free_decoder(pDecoder: PAc_decoder); cdecl; external ac_dll; diff --git a/Vocaluxe/Lib/Video/Acinerella/acinerella.c b/Vocaluxe/Lib/Video/Acinerella/acinerella.c index 3550bc07..5436d589 100644 --- a/Vocaluxe/Lib/Video/Acinerella/acinerella.c +++ b/Vocaluxe/Lib/Video/Acinerella/acinerella.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #define AUDIO_BUFFER_BASE_SIZE AVCODEC_MAX_AUDIO_FRAME_SIZE @@ -80,8 +81,8 @@ struct _ac_audio_decoder { ac_decoder decoder; int sought; double last_timecode; - uint8_t *tmp_data; - int tmp_data_length; + //uint8_t *tmp_data; + //int tmp_data_length; int max_buffer_size; AVCodec *pCodec; AVCodecContext *pCodecCtx; @@ -204,7 +205,7 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer( return (lp_ac_proberesult)fmt; } -#define PROBE_BUF_MIN 2048 +#define PROBE_BUF_MIN 1024 #define PROBE_BUF_MAX (1<<20) @@ -338,7 +339,7 @@ int CALL_CONVT ac_open( //Retrieve stream information AVFormatContext *ctx = ((lp_ac_data)pacInstance)->pFormatCtx; if(avformat_find_stream_info(ctx, NULL) >= 0) { - pacInstance->info.duration = ctx->duration * 1000 / AV_TIME_BASE; + pacInstance->info.duration = ctx->duration * 1000 / AV_TIME_BASE; } else { return -1; } @@ -350,6 +351,39 @@ int CALL_CONVT ac_open( return 0; } +int CALL_CONVT ac_open2(lp_ac_instance pacInstance, const char* filename) +{ + pacInstance->opened = 0; + + //Store the given parameters in the ac Instance + ((lp_ac_data)pacInstance)->sender = NULL; + ((lp_ac_data)pacInstance)->open_proc = NULL; + ((lp_ac_data)pacInstance)->read_proc = NULL; + ((lp_ac_data)pacInstance)->seek_proc = NULL; + ((lp_ac_data)pacInstance)->close_proc = NULL; + + /* open input file, and allocate format context */ + int ret = 0; + if ((ret = avformat_open_input(&((lp_ac_data)pacInstance)->pFormatCtx, filename, NULL, NULL)) < 0) + { + return ret; + } + + /* retrieve stream information */ + if ((ret = avformat_find_stream_info(((lp_ac_data)pacInstance)->pFormatCtx, NULL)) < 0) + { + return ret; + } + else + pacInstance->info.duration = ((lp_ac_data)pacInstance)->pFormatCtx->duration * 1000 / AV_TIME_BASE; + + //Set some information in the instance variable + pacInstance->stream_count = ((lp_ac_data)pacInstance)->pFormatCtx->nb_streams; + pacInstance->opened = pacInstance->stream_count > 0; + + return 0; +} + void CALL_CONVT ac_close(lp_ac_instance pacInstance) { if (pacInstance->opened) { //Close the opened file @@ -404,42 +438,13 @@ void CALL_CONVT ac_get_stream_info(lp_ac_instance pacInstance, int nb, lp_ac_str info->stream_type = AC_STREAM_TYPE_AUDIO; //Store more information about the video stream - info->audio_info.samples_per_second = + info->audio_info.samples_per_second = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->sample_rate; - info->audio_info.channel_count = - ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->channels; - - // Set bit depth - switch (((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->sample_fmt) { - //8-Bit - case AV_SAMPLE_FMT_U8: - info->audio_info.bit_depth = - 8; - break; - - //16-Bit - case AV_SAMPLE_FMT_S16: - info->audio_info.bit_depth = - 16; - break; - -/* //24-Bit (removed in the newest ffmpeg version) - case SAMPLE_FMT_S24: - info->additional_info.audio_info.bit_depth = - 24; - break; */ - - //32-Bit - case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_FLT: - info->audio_info.bit_depth = - 32; - break; - - //Unknown format, return zero - default: - info->audio_info.bit_depth = - 0; - } + info->audio_info.channel_count = 2; + //((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->channels; + + // Set bit depth (its always 16Bit because of the conversion! + info->audio_info.bit_depth = 16; break; default: @@ -501,89 +506,189 @@ enum PixelFormat convert_pix_format(ac_output_format fmt) { } //Init a video decoder -void* ac_create_video_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) { - //Allocate memory for a new decoder instance - lp_ac_video_decoder pDecoder; - pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder))); - memset(pDecoder, 0, sizeof(ac_video_decoder)); - - //Set a few properties - pDecoder->decoder.pacInstance = pacInstance; - pDecoder->decoder.type = AC_DECODER_TYPE_VIDEO; - pDecoder->decoder.stream_index = nb; - pDecoder->pCodecCtx = ((lp_ac_data)(pacInstance))->pFormatCtx->streams[nb]->codec; - pDecoder->decoder.stream_info = *info; - - //Find correspondenting codec - if (!(pDecoder->pCodec = avcodec_find_decoder(pDecoder->pCodecCtx->codec_id))) { - return NULL; //Codec could not have been found - } +void* _ac_create_video_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) { + //Allocate memory for a new decoder instance + lp_ac_video_decoder pDecoder; + pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder))); + memset(pDecoder, 0, sizeof(ac_video_decoder)); - pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be - // tested if there is a better solution + //Set a few properties + pDecoder->decoder.pacInstance = pacInstance; + pDecoder->decoder.type = AC_DECODER_TYPE_VIDEO; + pDecoder->decoder.stream_index = nb; + pDecoder->pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec; + pDecoder->decoder.stream_info = *info; + pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be + // tested if there is a better solution + + //Find correspondenting codec + if (!(pDecoder->pCodec = avcodec_find_decoder(pDecoder->pCodecCtx->codec_id))) + return NULL; //Codec could not have been found - //Open codec - if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0) { - return NULL; //Codec could not have been opened - } - - //Reserve frame variables - pDecoder->pFrame = avcodec_alloc_frame(); - pDecoder->pFrameRGB = avcodec_alloc_frame(); - - pDecoder->pSwsCtx = NULL; - - //Reserve buffer memory - pDecoder->decoder.buffer_size = avpicture_get_size(convert_pix_format(pacInstance->output_format), - pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height); - pDecoder->decoder.pBuffer = (uint8_t*)av_malloc(pDecoder->decoder.buffer_size); + //Open codec + if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0) + return NULL; //Codec could not have been opened - //Link decoder to buffer - avpicture_fill( - (AVPicture*)(pDecoder->pFrameRGB), - pDecoder->decoder.pBuffer, convert_pix_format(pacInstance->output_format), - pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height); - - return (void*)pDecoder; + //Reserve frame variables + pDecoder->pFrame = avcodec_alloc_frame(); + pDecoder->pFrameRGB = avcodec_alloc_frame(); + + pDecoder->pSwsCtx = NULL; + + //Reserve buffer memory + pDecoder->decoder.buffer_size = avpicture_get_size(convert_pix_format(pacInstance->output_format), + pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height); + pDecoder->decoder.pBuffer = (uint8_t*)av_malloc(pDecoder->decoder.buffer_size); + + //Link decoder to buffer + avpicture_fill( + (AVPicture*)(pDecoder->pFrameRGB), + pDecoder->decoder.pBuffer, convert_pix_format(pacInstance->output_format), + pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height); + + return (void*)pDecoder; } -//Init a audio decoder -void* ac_create_audio_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) { - //Allocate memory for a new decoder instance - lp_ac_audio_decoder pDecoder; - pDecoder = (lp_ac_audio_decoder)(av_malloc(sizeof(ac_audio_decoder))); - memset(pDecoder, 0, sizeof(ac_audio_decoder)); - - //Set a few properties - pDecoder->decoder.pacInstance = pacInstance; - pDecoder->decoder.type = AC_DECODER_TYPE_AUDIO; - pDecoder->decoder.stream_index = nb; - pDecoder->decoder.stream_info = *info; - pDecoder->decoder.video_clock = 0; - - //Temporary store codec context pointer - AVCodecContext *pCodecCtx = ((lp_ac_data)(pacInstance))->pFormatCtx->streams[nb]->codec; - pDecoder->pCodecCtx = pCodecCtx; - - //Find correspondenting codec - if (!(pDecoder->pCodec = avcodec_find_decoder(pCodecCtx->codec_id))) { - return NULL; - } - - //Open codec - if (avcodec_open2(pCodecCtx, pDecoder->pCodec, NULL) < 0) { - return NULL; - } - //Initialize the buffers - pDecoder->decoder.pBuffer = NULL; //av_malloc(AUDIO_BUFFER_BASE_SIZE); - pDecoder->decoder.buffer_size = 0; - pDecoder->max_buffer_size = 0; + +//Init a audio decoder +void* _ac_create_audio_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) { + //Allocate memory for a new decoder instance + lp_ac_audio_decoder pDecoder; + pDecoder = (lp_ac_audio_decoder)(av_malloc(sizeof(ac_audio_decoder))); + memset(pDecoder, 0, sizeof(ac_audio_decoder)); + + //Set a few properties + pDecoder->decoder.pacInstance = pacInstance; + pDecoder->decoder.type = AC_DECODER_TYPE_AUDIO; + pDecoder->decoder.stream_index = nb; + pDecoder->decoder.stream_info = *info; + pDecoder->decoder.video_clock = 0; + + //Temporary store codec context pointer + AVCodecContext *pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec; + pDecoder->pCodecCtx = pCodecCtx; + pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be + // tested if there is a better solution + + //Find correspondenting codec + if (!(pDecoder->pCodec = avcodec_find_decoder(pCodecCtx->codec_id))) + return NULL; + + //Open codec + if (avcodec_open2(pCodecCtx, pDecoder->pCodec, NULL) < 0) + return NULL; + + //Initialize the buffers + pDecoder->decoder.pBuffer = av_malloc(AUDIO_BUFFER_BASE_SIZE); + pDecoder->decoder.buffer_size = 0; + pDecoder->max_buffer_size = AUDIO_BUFFER_BASE_SIZE; + + //pDecoder->tmp_data = NULL; + //pDecoder->tmp_data_length = 0; + + return (void*)pDecoder; +} + +lp_ac_decoder CALL_CONVT ac_create_video_decoder(lp_ac_instance pacInstance) { + //Allocate memory for a new decoder instance + lp_ac_video_decoder pDecoder; + pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder))); + memset(pDecoder, 0, sizeof(ac_video_decoder)); + + int nb = av_find_best_stream(((lp_ac_data)pacInstance)->pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); + if (nb < 0) + return NULL; + + ac_stream_info info; + ac_get_stream_info(pacInstance, nb, &info); + + //Set a few properties + pDecoder->decoder.pacInstance = pacInstance; + pDecoder->decoder.type = AC_DECODER_TYPE_VIDEO; + pDecoder->decoder.stream_index = nb; + pDecoder->decoder.video_clock = 0; + ((lp_ac_decoder_data)pDecoder)->last_timecode = 0; + ((lp_ac_decoder_data)pDecoder)->sought = 1; + pDecoder->pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec; + pDecoder->decoder.stream_info = info; + pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be + // tested if there is a better solution + + //Find correspondenting codec + if (!(pDecoder->pCodec = avcodec_find_decoder(pDecoder->pCodecCtx->codec_id))) + return NULL; //Codec could not have been found + + //Open codec + if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0) + return NULL; //Codec could not have been opened + + //Reserve frame variables + pDecoder->pFrame = avcodec_alloc_frame(); + pDecoder->pFrameRGB = avcodec_alloc_frame(); + + pDecoder->pSwsCtx = NULL; + + //Reserve buffer memory + pDecoder->decoder.buffer_size = avpicture_get_size(convert_pix_format(pacInstance->output_format), + pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height); + pDecoder->decoder.pBuffer = (uint8_t*)av_malloc(pDecoder->decoder.buffer_size); + + //Link decoder to buffer + avpicture_fill( + (AVPicture*)(pDecoder->pFrameRGB), + pDecoder->decoder.pBuffer, convert_pix_format(pacInstance->output_format), + pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height); + + return (void*)pDecoder; +} + +lp_ac_decoder CALL_CONVT ac_create_audio_decoder(lp_ac_instance pacInstance) +{ + //Allocate memory for a new decoder instance + lp_ac_audio_decoder pDecoder; + pDecoder = (lp_ac_audio_decoder)(av_malloc(sizeof(ac_audio_decoder))); + memset(pDecoder, 0, sizeof(ac_audio_decoder)); + + int nb = av_find_best_stream(((lp_ac_data)pacInstance)->pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); + if (nb < 0) + return NULL; + + ac_stream_info info; + ac_get_stream_info(pacInstance, nb, &info); - pDecoder->tmp_data = NULL; - pDecoder->tmp_data_length = 0; - - return (void*)pDecoder; + //Set a few properties + pDecoder->decoder.pacInstance = pacInstance; + pDecoder->decoder.type = AC_DECODER_TYPE_AUDIO; + pDecoder->decoder.stream_index = nb; + pDecoder->decoder.stream_info = info; + pDecoder->decoder.video_clock = 0; + ((lp_ac_decoder_data)pDecoder)->last_timecode = 0; + ((lp_ac_decoder_data)pDecoder)->sought = 1; + + //Temporary store codec context pointer + AVCodecContext *pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec; + pDecoder->pCodecCtx = pCodecCtx; + pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be + // tested if there is a better solution + + //Find correspondenting codec + if (!(pDecoder->pCodec = avcodec_find_decoder(pCodecCtx->codec_id))) + return NULL; + + //Open codec + if (avcodec_open2(pCodecCtx, pDecoder->pCodec, NULL) < 0) + return NULL; + + //Initialize the buffers + pDecoder->decoder.pBuffer = av_malloc(AUDIO_BUFFER_BASE_SIZE); + pDecoder->decoder.buffer_size = 0; + pDecoder->max_buffer_size = AUDIO_BUFFER_BASE_SIZE; + + //pDecoder->tmp_data = NULL; + //pDecoder->tmp_data_length = 0; + + return (void*)pDecoder; } lp_ac_decoder CALL_CONVT ac_create_decoder(lp_ac_instance pacInstance, int nb) { @@ -595,12 +700,15 @@ lp_ac_decoder CALL_CONVT ac_create_decoder(lp_ac_instance pacInstance, int nb) { lp_ac_decoder result; if (info.stream_type == AC_STREAM_TYPE_VIDEO) { - result = ac_create_video_decoder(pacInstance, &info, nb); + result = _ac_create_video_decoder(pacInstance, &info, nb); } else if (info.stream_type == AC_STREAM_TYPE_AUDIO) { - result = ac_create_audio_decoder(pacInstance, &info, nb); + result = _ac_create_audio_decoder(pacInstance, &info, nb); } + if (result == NULL) + return NULL; + ((lp_ac_decoder_data)result)->last_timecode = 0; ((lp_ac_decoder_data)result)->sought = 1; result->video_clock = 0; @@ -643,13 +751,7 @@ int ac_decode_video_package(lp_ac_package pPackage, lp_ac_video_decoder pDecoder pkt_tmp.size -= len; pkt_tmp.data += len; } - - /* - avcodec_decode_video2( - pDecoder->pCodecCtx, pDecoder->pFrame, &finished, - &(((lp_ac_package_data)pPackage)->ffpackage)); - */ - + if (finished != 0) { pDecoder->pSwsCtx = sws_getCachedContext(pDecoder->pSwsCtx, pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height, pDecoder->pCodecCtx->pix_fmt, @@ -687,6 +789,18 @@ int ac_decode_video_package(lp_ac_package pPackage, lp_ac_video_decoder pDecoder return 0; } +int alloc_samples_array_and_data(uint8_t ***data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align) +{ + int nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1; + + *data = av_malloc(sizeof(*data) * nb_planes); + if (!*data) + return AVERROR(ENOMEM); + return av_samples_alloc(*data, linesize, nb_channels, + nb_samples, sample_fmt, align); +} + int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder, lp_ac_decoder pDec) { double pts; //Variables describing the destination buffer @@ -694,17 +808,18 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder //Make a copy of the package read by avformat, so that we can move the data pointers around AVPacket pkt_tmp = ((lp_ac_package_data)pPackage)->ffpackage; - + AVFrame *decoded_frame = NULL; - + + /* if (pDecoder->tmp_data_length > 0) { pkt_tmp.data = av_realloc(pkt_tmp.data, pkt_tmp.size + pDecoder->tmp_data_length); + memmove(pkt_tmp.data + pDecoder->tmp_data_length, pkt_tmp.data, pkt_tmp.size); + memcpy(pkt_tmp.data, pDecoder->tmp_data, pDecoder->tmp_data_length); pkt_tmp.size = pkt_tmp.size + pDecoder->tmp_data_length; - memcpy(pkt_tmp.data + pDecoder->tmp_data_length, &pkt_tmp.data, pkt_tmp.size); - memcpy(&pkt_tmp.data, pDecoder->tmp_data, pDecoder->tmp_data_length); - } - + } */ + while (pkt_tmp.size > 0) { if (!decoded_frame) { @@ -718,7 +833,6 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder int len1 = avcodec_decode_audio4(pDecoder->pCodecCtx, decoded_frame, &got_frame, &pkt_tmp); - //If an error occured, skip the frame if (len1 < 0){ return 0; @@ -729,54 +843,107 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder pkt_tmp.data += len1; if (got_frame){ - - int data_size = av_samples_get_buffer_size(NULL, (pDecoder->pCodecCtx)->channels, - decoded_frame->nb_samples, - (pDecoder->pCodecCtx)->sample_fmt, 1); - - //Reserve enough memory for coping the result data - if (dest_buffer_pos + data_size > pDecoder->max_buffer_size) { - pDecoder->decoder.pBuffer = av_realloc(pDecoder->decoder.pBuffer, dest_buffer_pos + data_size); - pDecoder->max_buffer_size = dest_buffer_pos + data_size; - } - memcpy(pDecoder->decoder.pBuffer + dest_buffer_pos, decoded_frame->data[0], data_size); - - //Increment the destination buffer pointers, copy the result to the output buffer - dest_buffer_pos += data_size; - pDecoder->decoder.buffer_size += data_size; - - - pts=0; - - if(((lp_ac_package_data)pPackage)->ffpackage.dts != AV_NOPTS_VALUE){ - pts = ((lp_ac_package_data)pPackage)->ffpackage.dts * av_q2d(((lp_ac_data)pDec->pacInstance)->pFormatCtx->streams[pPackage->stream_index]->time_base); - - pDec->video_clock = pts; - } else { - pts = pDec->video_clock; - } - - double bytes_per_second = 2 * pDec->stream_info.audio_info.samples_per_second * pDec->stream_info.audio_info.channel_count; - if (bytes_per_second > 0) - pDec->video_clock += data_size / bytes_per_second; + struct SwrContext *swr_ctx; + int dst_nb_samples = 0, max_dst_nb_samples = 0, dst_linesize = 0; + uint8_t **dst_data = NULL; + int ret = 0; + int dst_sample_rate = (pDecoder->pCodecCtx)->sample_rate; - pDec->timecode = pts; + swr_ctx = swr_alloc(); - if (pkt_tmp.size > 0) - { - pDecoder->tmp_data = av_malloc(pkt_tmp.size); - memcpy(pDecoder->tmp_data, &pkt_tmp.data, pkt_tmp.size); - } else { - av_free(pDecoder->tmp_data); - pDecoder->tmp_data_length = 0; - } + /* set options */ + av_opt_set_int(swr_ctx, "in_channel_layout", (pDecoder->pCodecCtx)->channel_layout, 0); + av_opt_set_int(swr_ctx, "in_sample_rate", (pDecoder->pCodecCtx)->sample_rate, 0); + av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", (pDecoder->pCodecCtx)->sample_fmt, 0); + + av_opt_set_int(swr_ctx, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); + av_opt_set_int(swr_ctx, "out_sample_rate", dst_sample_rate, 0); + av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + + if (swr_init(swr_ctx) < 0) + return 0; + + /* compute the number of converted samples: buffering is avoided + * ensuring that the output buffer will contain at least all the + * converted input samples */ + max_dst_nb_samples = dst_nb_samples = av_rescale_rnd( + decoded_frame->nb_samples, dst_sample_rate, (pDecoder->pCodecCtx)->sample_rate, AV_ROUND_UP); + + if (alloc_samples_array_and_data(&dst_data, &dst_linesize, 2, dst_nb_samples, AV_SAMPLE_FMT_S16, 0) < 0) + return 0; + + /* compute destination number of samples */ + dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, (pDecoder->pCodecCtx)->sample_rate) + + decoded_frame->nb_samples, dst_sample_rate, (pDecoder->pCodecCtx)->sample_rate, AV_ROUND_UP); + + if (dst_nb_samples > max_dst_nb_samples) { + av_free(dst_data[0]); + ret = av_samples_alloc(dst_data, &dst_linesize, 2, + dst_nb_samples, AV_SAMPLE_FMT_S16, 1); + if (ret < 0) + return 0; + max_dst_nb_samples = dst_nb_samples; + } + + if ((ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)decoded_frame->data, decoded_frame->nb_samples)) < 0) + return 0; + + int data_size = av_samples_get_buffer_size(&dst_linesize, 2, ret, AV_SAMPLE_FMT_S16, 1); + + //Reserve enough memory for coping the result data + if (dest_buffer_pos + data_size > pDecoder->max_buffer_size) { + pDecoder->decoder.pBuffer = av_realloc(pDecoder->decoder.pBuffer, dest_buffer_pos + data_size); + pDecoder->max_buffer_size = dest_buffer_pos + data_size; + } + + memcpy(pDecoder->decoder.pBuffer + dest_buffer_pos, dst_data[0], data_size); + + //Increment the destination buffer pointers, copy the result to the output buffer + dest_buffer_pos += data_size; + pDecoder->decoder.buffer_size += data_size; + + pts=0; + + if(((lp_ac_package_data)pPackage)->ffpackage.dts != AV_NOPTS_VALUE){ + pts = ((lp_ac_package_data)pPackage)->ffpackage.dts * av_q2d(((lp_ac_data)pDec->pacInstance)->pFormatCtx->streams[pPackage->stream_index]->time_base); - return 1; + pDec->video_clock = pts; + } else { + pts = pDec->video_clock; + } + + double bytes_per_second = 4 * pDec->stream_info.audio_info.samples_per_second; + if (bytes_per_second > 0) + pDec->video_clock += data_size / bytes_per_second; + + pDec->timecode = pts; + + /* + if (pkt_tmp.size > 0) + { + pDecoder->tmp_data = av_malloc(pkt_tmp.size); + memcpy(pDecoder->tmp_data, pkt_tmp.data, pkt_tmp.size); + pDecoder->tmp_data_length = pkt_tmp.size; + } else { + if (pDecoder->tmp_data_length > 0) + { + av_free(pDecoder->tmp_data); + pDecoder->tmp_data_length = 0; + } + } + */ + + if (dst_data) + av_freep(&dst_data[0]); + av_freep(&dst_data); + + swr_free(&swr_ctx); + return 1; } } - av_free(pDecoder->tmp_data); - pDecoder->tmp_data_length; + //av_free(pDecoder->tmp_data); + //pDecoder->tmp_data_length = 0; return 0; } @@ -852,11 +1019,10 @@ int CALL_CONVT ac_get_audio_frame(lp_ac_instance pacInstance, lp_ac_decoder pDec while(done == 0 && pPackage != NULL){ if (((lp_ac_package_data)pPackage)->package.stream_index == pDecoder->stream_index){ done = ac_decode_package(pPackage, pDecoder); - ac_free_package(pPackage); - if (((lp_ac_audio_decoder)pDecoder)->decoder.buffer_size < 4096) - done = 0; + //if (((lp_ac_audio_decoder)pDecoder)->decoder.buffer_size < 17640) + // done = 0; if (done == 0) pPackage = ac_read_package(pacInstance); @@ -952,8 +1118,8 @@ int CALL_CONVT ac_seek(lp_ac_decoder pDecoder, int dir, int64_t target_pos) { if (((lp_ac_audio_decoder)pDecoder)->pCodecCtx->codec->flush != NULL) avcodec_flush_buffers(((lp_ac_audio_decoder)pDecoder)->pCodecCtx); - av_free(((lp_ac_audio_decoder)pDecoder)->tmp_data); - ((lp_ac_audio_decoder)pDecoder)->tmp_data_length = 0; + //av_free(((lp_ac_audio_decoder)pDecoder)->tmp_data); + //((lp_ac_audio_decoder)pDecoder)->tmp_data_length = 0; } return 1; } @@ -986,7 +1152,7 @@ void ac_free_audio_decoder(lp_ac_audio_decoder pDecoder) { av_free(pDecoder->decoder.pBuffer); //Free the memory reserved for the temporary audio buffer - av_free(pDecoder->tmp_data); + //av_free(pDecoder->tmp_data); //Free reserved memory for decoder record av_free(pDecoder); diff --git a/Vocaluxe/Lib/Video/Acinerella/acinerella.h b/Vocaluxe/Lib/Video/Acinerella/acinerella.h index 203d8750..064eff6f 100644 --- a/Vocaluxe/Lib/Video/Acinerella/acinerella.h +++ b/Vocaluxe/Lib/Video/Acinerella/acinerella.h @@ -113,7 +113,7 @@ struct _ac_audio_stream_info { /*Bits per sample. Can be 8 or 16 Bit.*/ int bit_depth; /*Count of channels in the audio stream.*/ - int channel_count; + int channel_count; }; typedef struct _ac_audio_stream_info ac_audio_stream_info; @@ -205,6 +205,12 @@ extern int CALL_CONVT ac_open( ac_seek_callback seek_proc, ac_openclose_callback close_proc, lp_ac_proberesult proberesult); + +extern int CALL_CONVT ac_open2( + lp_ac_instance pacInstance, + const char* filename +); + /*Closes an opened media file.*/ extern void CALL_CONVT ac_close(lp_ac_instance pacInstance); @@ -219,6 +225,8 @@ extern void CALL_CONVT ac_free_package(lp_ac_package pPackage); /*Creates an decoder for the specified stream number. Returns NIL if no decoder could be found.*/ extern lp_ac_decoder CALL_CONVT ac_create_decoder(lp_ac_instance pacInstance, int nb); +extern lp_ac_decoder CALL_CONVT ac_create_audio_decoder(lp_ac_instance pacInstance); +extern lp_ac_decoder CALL_CONVT ac_create_video_decoder(lp_ac_instance pacInstance); /*Frees an created decoder.*/ extern void CALL_CONVT ac_free_decoder(lp_ac_decoder pDecoder); /*Decodes a package using the specified decoder. The decodec data is stored in the diff --git a/Vocaluxe/Lib/Video/Acinerella/makefile b/Vocaluxe/Lib/Video/Acinerella/makefile index 1a823680..cf3c9325 100644 --- a/Vocaluxe/Lib/Video/Acinerella/makefile +++ b/Vocaluxe/Lib/Video/Acinerella/makefile @@ -2,9 +2,9 @@ acinerella: acinerella.c acinerella.h gcc -c acinerella.c -I /usr/local/include ifeq ($(shell uname),Linux) - gcc -shared -o libacinerella.so acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale + gcc -shared -o libacinerella.so acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lswresample strip libacinerella.so else - gcc -shared -o acinerella.dll -fPIC acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lws2_32 + gcc -shared -o acinerella.dll -fPIC acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lws2_32 -lswresample strip acinerella.dll endif diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs index 9b0f7828..ed759756 100644 --- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs +++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs @@ -267,8 +267,8 @@ namespace Vocaluxe.Lib.Video public Decoder() { - _rc = new TAc_read_callback(read_proc); - _sc = new TAc_seek_callback(seek_proc); + //_rc = new TAc_read_callback(read_proc); + //_sc = new TAc_seek_callback(seek_proc); _thread = new Thread(Execute); } @@ -485,56 +485,45 @@ namespace Vocaluxe.Lib.Video private void DoOpen() { - bool ok = false; TAc_instance Instance = new TAc_instance(); + + _instance = CAcinerella.ac_init(); + int ret = -1; + if ((ret = CAcinerella.ac_open2(_instance, _FileName)) < 0) + { + CLog.LogError("Error opening video file (Errorcode: " + ret.ToString() + "): " + _FileName); + return; + } + + Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance)); + + if (!Instance.opened || Instance.info.duration == 0) + { + if (!Instance.opened) + CLog.LogError("Can't open video file: " + _FileName); + else + CLog.LogError("Can't open video file (length = 0?): " + _FileName); + return; + } + try { - _fs = new FileStream(_FileName, FileMode.Open, FileAccess.Read, FileShare.Read); - - - _instance = CAcinerella.ac_init(); - CAcinerella.ac_open(_instance, IntPtr.Zero, null, _rc, _sc, null, IntPtr.Zero); - - Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance)); - ok = true; + _videodecoder = CAcinerella.ac_create_video_decoder(_instance); } - catch (Exception) + catch (Exception e) { - CLog.LogError("Error opening video file: " + _FileName); - ok = false; + CLog.LogError("Can't create video decoder for file: " + _FileName + "; " + e.Message); + return; } - - if (!Instance.opened || !ok) + if (_videodecoder == IntPtr.Zero) { - //Free(); + CLog.LogError("Can't create video decoder for file: " + _FileName); return; } _Duration = (float)Instance.info.duration / 1000f; - int VideoStreamIndex = -1; - - TAc_stream_info Info = new TAc_stream_info(); - for (int i = 0; i < Instance.stream_count; i++) - { - CAcinerella.ac_get_stream_info(_instance, i, out Info); - - if (Info.stream_type == TAc_stream_type.AC_STREAM_TYPE_VIDEO) - { - _videodecoder = CAcinerella.ac_create_decoder(_instance, i); - - VideoStreamIndex = i; - break; - } - } - - if (VideoStreamIndex < 0) - { - //Free(); - return; - } - TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder)); _Width = Videodecoder.stream_info.video_info.frame_width; diff --git a/Vocaluxe/Screens/CScreenNames.cs b/Vocaluxe/Screens/CScreenNames.cs index 38cac5cd..5b127b27 100644 --- a/Vocaluxe/Screens/CScreenNames.cs +++ b/Vocaluxe/Screens/CScreenNames.cs @@ -612,9 +612,9 @@ namespace Vocaluxe.Screens SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].AddValue(CGame.GetSong(1).DuetPart1); SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].AddValue(CGame.GetSong(1).DuetPart2); if ((i + 1) % 2 == 0) - SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].SetSelectionByValueIndex(1); + SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].Selection = 1; else - SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].SetSelectionByValueIndex(0); + SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].Selection = 0; } else SelectSlides[htSelectSlides(SelectSlideDuetPlayer[i])].Visible = false;