-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
205 lines (149 loc) · 7 KB
/
Program.cs
File metadata and controls
205 lines (149 loc) · 7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
CREDITS TO gh/viliusi FOR THE ORIGINAL PROJECT (https://github.com/viliusi/Bad-Apple-CSharp/)
CREDITS TO gh/Chion82 FOR THE ORIGINAL CONVERSION TOOL (https://github.com/Chion82/ASCII_bad_apple)
CREDITS TO yt/Raveyboi FOR THE HI-FI AUDIO (https://youtu.be/QOeShlDRSas?si=1HyQt2jEOSc0L3Kr)
CREDITS TO yt/avrilloosing (aka YoshiFan) FOR THE 60FPS VIDEO (https://youtu.be/ThHvx5a9IYA?si=rBtA6xr4MJEjBdAv)
Changes made on this version: (06/03/2025)
- Replaced some characters from the frames file for a cleaner view.
- Set console sizes (tested on Windows) which were missing on the original version.
- Added audio playback using NAudio + Tried my best to sync music and visual
- Speed changed to match the original video (60fps version)
*/
using NAudio.Wave;
using System.Diagnostics;
public class Program
{
static void Main()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
String debug = Directory.GetCurrentDirectory();
String allFrames = debug + "/b/test60.txt";
String soundtrack = debug + "/b/soundtrack.mp3"; // Set audio as well
Console.BackgroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Black;
Console.Title = "(New) Bad Apple C#";
// Set the console sizes so no flashy imagery takes place
Console.SetWindowSize(151, 45);
string line;
// THIS IS NOT PERFECT AND MAY DESYNC FROM THE VIDEO
using var audioFile = new AudioFileReader(soundtrack);
using var outputDevice = new WaveOutEvent();
outputDevice.Init(audioFile);
outputDevice.Play();
int framesInSecond = 0;
double fps = 0;
Stopwatch fpsTimer = Stopwatch.StartNew();
Thread.Sleep(100); // Wait for the audio
Stopwatch stopwatch = Stopwatch.StartNew(); // Starts at the same time as the audio
// Thread musicThread = new Thread(() => PlayMusic(soundtrack));
// musicThread.IsBackground = true;
// musicThread.Start();
try
{
StreamReader sr = new StreamReader(allFrames);
line = sr.ReadLine();
bool split;
List<string> currentFrame = new List<string>();
int frameCount = 0; // Know the frame to sync
double frameDuration = 1000.0 / 60.0; // Aprox. 60fps (some frames are lost during conversion)
// musicThread.Start(); // This ended up not working :(
while (line != null)
{
switch (line)
{
case var containsSplit when line.Contains("SPLIT"):
split = true;
// This kinda resembles analog tv haha
line = sr.ReadLine();
line = sr.ReadLine();
break;
default:
split = false;
currentFrame.Add(line);
line = sr.ReadLine();
break;
}
switch (split)
{
case true:
/*
currentFrame.ForEach(i => Console.Write("{0}\n", i));
currentFrame.Clear();
// Original code used this - not needed anymore as now it is real time
// Thread.Sleep(50);
Console.SetCursorPosition(0, 0);
// My best attempt for a proper audio sync
double targetTime = frameCount * frameDuration;
double elapsedTime = stopwatch.Elapsed.TotalMilliseconds;
double sleepTime = targetTime - elapsedTime;
if (sleepTime > 0)
Thread.Sleep((int)sleepTime);
frameCount++;
break;
*/
double desfase = stopwatch.Elapsed.TotalMilliseconds - (frameCount * frameDuration);
Console.SetCursorPosition(0, 0); // Asegurar que empieza desde la parte superior
currentFrame.ForEach(i => Console.WriteLine(i)); // Imprimir el frame
currentFrame.Clear();
// Mueve el cursor a la parte inferior de la consola
Console.SetCursorPosition(0, Console.WindowHeight - 2);
Console.WriteLine($"Timestamp: {frameCount / 60:D2}:{frameCount % 60:D2} | Frame: {frameCount} | FPS: {fps:0.0} | Sync Offset: {desfase:+0.0;-0.0} ms ");
// Sincronización de tiempo
double targetTime = frameCount * frameDuration;
double elapsedTime = stopwatch.Elapsed.TotalMilliseconds;
double sleepTime = targetTime - elapsedTime;
if (sleepTime > 0)
Thread.Sleep((int)sleepTime);
frameCount++;
framesInSecond++;
if (fpsTimer.ElapsedMilliseconds >= 1000)
{
fps = framesInSecond / (fpsTimer.ElapsedMilliseconds / 1000.0); // FPS real
framesInSecond = 0;
fpsTimer.Restart();
}
break;
case false:
break;
default:
break;
}
}
}
finally
{
Console.Clear();
Console.SetCursorPosition(0, 0);
Console.WriteLine("\n\n\n\n\n\n\n\n\n\n\n\n\n \"Hope you enjoyed the work, while I myself didn't do too much of the work, I'm still proud of what I achieved :)\"\n - viliusi\n\n Support both projects!\n - ggsplayz\n\n https://github.com/viliusi/Bad-Apple-CSharp/\n https://github.com/ggsplayz/BadApple");
Console.ReadKey();
}
}
/*
* This is not needed anymore
*
static void PlayMusic(string path)
{
using var audioFile = new AudioFileReader(path);
using var outputDevice = new WaveOutEvent();
outputDevice.Init(audioFile);
outputDevice.Play();
// Wait for the playback to end, just in case
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(500);
}
}
*/
// Left just in case - not needed right now
static void PreciseSleep(double milliseconds)
{
int intPart = (int)milliseconds; // Int
double fracPart = milliseconds - intPart; // Decimals
Thread.Sleep(intPart);
if (fracPart > 0)
{
Stopwatch stopwatch = Stopwatch.StartNew();
while (stopwatch.Elapsed.TotalMilliseconds < fracPart) { }
}
}
}