Commit 4da27c41 for whisper.cpp

commit 4da27c41cebadb3cbbcd2563e9c7cbc8d84bdcad
Author: Vincenzo Reina <vincenzoreinaa05@gmail.com>
Date:   Tue Nov 3 07:04:32 2026 +0100

    cli : fix stdout of model on windows (#4146)

diff --git a/examples/cli/cli.cpp b/examples/cli/cli.cpp
index 3652c76c..16f50c02 100644
--- a/examples/cli/cli.cpp
+++ b/examples/cli/cli.cpp
@@ -7,6 +7,7 @@
 #include <cmath>
 #include <algorithm>
 #include <fstream>
+#include <iostream>
 #include <cstdio>
 #include <string>
 #include <thread>
@@ -452,7 +453,7 @@ static void whisper_print_segment_callback(struct whisper_context * ctx, struct
     }
 }

-static void output_txt(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
+static void output_txt(struct whisper_context * ctx, std::ostream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
     const int n_segments = whisper_full_n_segments(ctx);
     for (int i = 0; i < n_segments; ++i) {
         const char * text = whisper_full_get_segment_text(ctx, i);
@@ -477,7 +478,7 @@ static void output_txt(struct whisper_context * ctx, std::ofstream & fout, const
     }
 }

-static void output_vtt(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
+static void output_vtt(struct whisper_context * ctx, std::ostream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
     fout << "WEBVTT\n\n";

     const int n_segments = whisper_full_n_segments(ctx);
@@ -499,7 +500,7 @@ static void output_vtt(struct whisper_context * ctx, std::ofstream & fout, const
     }
 }

-static void output_srt(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
+static void output_srt(struct whisper_context * ctx, std::ostream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
     const int n_segments = whisper_full_n_segments(ctx);
     for (int i = 0; i < n_segments; ++i) {
         const char * text = whisper_full_get_segment_text(ctx, i);
@@ -581,7 +582,7 @@ static char * escape_double_quotes_in_csv(const char * str) {
     return escaped;
 }

-static void output_csv(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
+static void output_csv(struct whisper_context * ctx, std::ostream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
     const int n_segments = whisper_full_n_segments(ctx);
     fout << "start,end,";
     if (params.diarize && pcmf32s.size() == 2)
@@ -606,7 +607,7 @@ static void output_csv(struct whisper_context * ctx, std::ofstream & fout, const
     }
 }

-static void output_score(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & /*params*/, std::vector<std::vector<float>> /*pcmf32s*/) {
+static void output_score(struct whisper_context * ctx, std::ostream & fout, const whisper_params & /*params*/, std::vector<std::vector<float>> /*pcmf32s*/) {
     const int n_segments = whisper_full_n_segments(ctx);
     // fprintf(stderr,"segments: %d\n",n_segments);
     for (int i = 0; i < n_segments; ++i) {
@@ -623,7 +624,7 @@ static void output_score(struct whisper_context * ctx, std::ofstream & fout, con

 static void output_json(
              struct whisper_context * ctx,
-                      std::ofstream & fout,
+                       std::ostream & fout,
                const whisper_params & params,
     std::vector<std::vector<float>>   pcmf32s) {
     const bool full = params.output_jsn_full;
@@ -813,7 +814,7 @@ static void output_json(
 // karaoke video generation
 // outputs a bash script that uses ffmpeg to generate a video with the subtitles
 // TODO: font parameter adjustments
-static bool output_wts(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s, const char * fname_inp, float t_sec, const char * fname_out) {
+static bool output_wts(struct whisper_context * ctx, std::ostream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s, const char * fname_inp, float t_sec, const char * fname_out) {
     static const char * font = params.font_path.c_str();

     std::ifstream fin(font);
@@ -927,14 +928,12 @@ static bool output_wts(struct whisper_context * ctx, std::ofstream & fout, const
     fout << "echo \"  ffplay " << fname_inp << ".mp4\"\n";
     fout << "\n";

-    fout.close();
-
     fprintf(stderr, "# %s: run 'source %s' to generate karaoke video\n", __func__, fname_out);

     return true;
 }

-static void output_lrc(struct whisper_context * ctx, std::ofstream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
+static void output_lrc(struct whisper_context * ctx, std::ostream & fout, const whisper_params & params, std::vector<std::vector<float>> pcmf32s) {
     fout << "[by:whisper.cpp]\n";

     const int n_segments = whisper_full_n_segments(ctx);
@@ -1131,6 +1130,7 @@ int main(int argc, char ** argv) {
             bool failed;
             decltype(whisper_print_segment_callback) * const print_segment_callback;
             std::ofstream fout;
+            std::ostream * out = nullptr;

             fout_factory (const std::string & fname_out_, const std::string & fname_inp, whisper_params & params) :
                     fname_out{!fname_out_.empty() ? fname_out_ : fname_inp},
@@ -1152,13 +1152,7 @@ int main(int argc, char ** argv) {
                     }

                     used_stdout = true;
-#ifdef _WIN32
-                    fout = std::ofstream{"CON"};
-#else
-                    fout = std::ofstream{"/dev/stdout"};
-#endif
-                    // Not using fprintf stderr here because it might equal stdout
-                    // Also assuming /dev is mounted
+                    out = &std::cout;
                     return true;
                 }

@@ -1171,6 +1165,7 @@ int main(int argc, char ** argv) {
                     return false;
                 }
                 fprintf(stderr, "%s: saving output to '%s'\n", function, fname_out.c_str());
+                out = &fout;
                 return true;
             }
         } fout_factory{f < (int) params.fname_out.size() ? params.fname_out[f] : "", fname_inp, params};
@@ -1340,7 +1335,8 @@ int main(int argc, char ** argv) {
         {
             // macros to stringify function name
 #define output_func(func, ext, param, ...) if (param && fout_factory.open(ext, #func)) {\
-    func(ctx, fout_factory.fout, params, __VA_ARGS__); \
+    func(ctx, *fout_factory.out, params, __VA_ARGS__); \
+    fout_factory.out->flush(); \
 }
 #define output_ext(ext, ...) output_func(output_##ext, "." #ext, params.output_##ext, __VA_ARGS__)