Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kew for openSUSE:Factory checked in 
at 2023-12-01 21:26:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kew (Old)
 and      /work/SRC/openSUSE:Factory/.kew.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kew"

Fri Dec  1 21:26:03 2023 rev:4 rq:1130123 version:1.8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/kew/kew.changes  2023-11-27 22:43:58.471161516 
+0100
+++ /work/SRC/openSUSE:Factory/.kew.new.25432/kew.changes       2023-12-01 
21:26:40.400753946 +0100
@@ -1,0 +2,28 @@
+Wed Nov 29 12:05:29 UTC 2023 - Muhammad Akbar Yanuar Mantari <mantari...@pm.me>
+
+- Update to version 1.8.1
+  * Fixed bug where kew for no reason stopped playing audio but
+    kept counting elapsed seconds.
+  * Fixed bugs relating to showing the playlist.
+  * Fixed bug where trying to seek in ogg files led to strange
+    behavior. Now seeking in ogg is entirely disabled.
+  * More colorful visualizer bars when using album cover colors.
+
+-------------------------------------------------------------------
+Tue Nov 28 00:27:10 UTC 2023 - Muhammad Akbar Yanuar Mantari <mantari...@pm.me>
+
+- Update to version 1.8
+  * visualizer bars now grow and decrease smoothly (if your
+    terminal supports unicode).
+  * m4a files quit properly.
+
+-------------------------------------------------------------------
+Mon Nov 27 10:18:38 UTC 2023 - Muhammad Akbar Yanuar Mantari <mantari...@pm.me>
+
+- Update to version 1.7.4
+  * kew is now interactive when paused.
+  * Fixed issue with crashing after a few plays with repeat
+    enabled.
+  * Deletes cover images from cache after playing the file.
+
+-------------------------------------------------------------------

Old:
----
  kew-1.7.3.tar.gz

New:
----
  kew-1.8.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kew.spec ++++++
--- /var/tmp/diff_new_pack.hUONxd/_old  2023-12-01 21:26:41.244784945 +0100
+++ /var/tmp/diff_new_pack.hUONxd/_new  2023-12-01 21:26:41.256785386 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           kew
-Version:        1.7.3
+Version:        1.8.1
 Release:        0
 Summary:        A command-line music player
 License:        GPL-2.0-only

++++++ kew-1.7.3.tar.gz -> kew-1.8.1.tar.gz ++++++
Binary files old/kew-1.7.3/kew-screenshot.png and 
new/kew-1.8.1/kew-screenshot.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/cache.c new/kew-1.8.1/src/cache.c
--- old/kew-1.7.3/src/cache.c   2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/cache.c   2023-11-29 01:42:25.000000000 +0100
@@ -51,4 +51,18 @@
                 remove(current->filePath);
                 current = current->next;
         }
+}
+
+bool existsInCache(Cache *cache, char *filePath)
+{
+        CacheNode *current = cache->head;
+        while (current != NULL)
+        {
+                if (strcmp(filePath, current->filePath) == 0)
+                {
+                        return true;
+                }
+                current = current->next;
+        } 
+        return false;       
 }
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/cache.h new/kew-1.8.1/src/cache.h
--- old/kew-1.7.3/src/cache.h   2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/cache.h   2023-11-29 01:42:25.000000000 +0100
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 typedef struct CacheNode
 {
@@ -25,4 +26,6 @@
 
 void deleteCachedFiles(Cache *cache);
 
+bool existsInCache(Cache *cache, char *filePath);
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/kew.c new/kew-1.8.1/src/kew.c
--- old/kew-1.7.3/src/kew.c     2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/kew.c     2023-11-29 01:42:25.000000000 +0100
@@ -413,6 +413,8 @@
 
 void handleGoToSong()
 {
+        resetPlaylistDisplay = true;
+        
         if (digitsPressedCount == 0)
         {
                 skipToNumberedSong(chosenSong + 1);
@@ -424,7 +426,7 @@
                 memset(digitsPressed, '\0', sizeof(digitsPressed));
                 digitsPressedCount = 0;
                 skipToNumberedSong(songNumber);
-        }
+        }        
 }
 
 void gotoBeginningOfPlaylist()
@@ -498,10 +500,12 @@
         case EVENT_VOLUME_DOWN:
                 adjustVolumePercent(-5);
                 break;
-        case EVENT_NEXT:
+        case EVENT_NEXT:     
+                resetPlaylistDisplay = true;
                 skipToNextSong();
                 break;
         case EVENT_PREV:
+                resetPlaylistDisplay = true; 
                 skipToPrevSong();
                 break;
         case EVENT_SEEKBACK:
@@ -748,6 +752,7 @@
         loadingdata.songdataB = NULL;
         loadingdata.loadA = true;
         initAudioBuffer();
+        initVisuals();
 
 #ifdef DEBUG
         g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/player.c new/kew-1.8.1/src/player.c
--- old/kew-1.7.3/src/player.c  2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/player.c  2023-11-29 01:42:25.000000000 +0100
@@ -23,9 +23,9 @@
 } PixelData;
 #endif
 
-const char VERSION[] = "1.7.3";
+const char VERSION[] = "1.8.1";
 const int LOGO_COLOR = 3;
-const int VERSION_COLOR = 6;
+const int VERSION_COLOR = 2;
 const int ABSOLUTE_MIN_WIDTH = 38;
 volatile bool refresh = true;
 bool visualizerEnabled = true;
@@ -35,12 +35,11 @@
 bool timeEnabled = true;
 bool drewCover = true;
 bool uiEnabled = true;
-bool printInfo = false;
+bool printPlaylist = false;
 bool printKeyBindings = false;
 bool showList = true;
 bool resetPlaylistDisplay = true;
 bool useProfileColors = true;
-bool hasPrintedPaused = false;
 bool fastForwarding = false;
 bool rewinding = false;
 int numProgressBars = 15;
@@ -362,7 +361,7 @@
 }
 void printMetadata(TagSettings const *metadata)
 {
-        if (!metaDataEnabled || printInfo)
+        if (!metaDataEnabled || printPlaylist)
                 return;
         c_sleep(100);
         setColor();
@@ -371,7 +370,7 @@
 
 void printTime(PlayList const *playlist)
 {
-        if (!timeEnabled || printInfo)
+        if (!timeEnabled || printPlaylist)
                 return;
         setColor();
         int term_w, term_h;
@@ -621,7 +620,7 @@
 void toggleShowPlaylist()
 {
         refresh = true;
-        printInfo = !printInfo;
+        printPlaylist = !printPlaylist;
         printKeyBindings = false;
 }
 
@@ -629,12 +628,12 @@
 {
         refresh = true;
         printKeyBindings = !printKeyBindings;
-        printInfo = false;
+        printPlaylist = false;
 }
 
 void scrollNext()
 {
-        if (printInfo)
+        if (printPlaylist)
         {
                 chosenRow++;
                 refresh = true;
@@ -643,7 +642,7 @@
 
 void scrollPrev()
 {
-        if (printInfo)
+        if (printPlaylist)
         {
                 chosenRow--;
                 refresh = true;
@@ -714,7 +713,7 @@
 
         if (chosenSong < startIter)
         {
-                startIter = chosenSong;
+                startIter = chosenSong;   
         }
 
         if (chosenRow >= maxListSize - 1 && chosenRow > startIter + 
maxListSize - 1)
@@ -731,6 +730,7 @@
         {
                 startIter = chosenRow = chosenSong = foundAt;
         }
+        
         for (int i = foundAt; i > startIter; i--)
         {
                 if (i > 0 && node->prev != NULL)
@@ -841,7 +841,7 @@
 
 void printVisualizer()
 {
-        if (visualizerEnabled && !printInfo)
+        if (visualizerEnabled && !printPlaylist)
         {
                 printf("\n");
                 int term_w, term_h;
@@ -891,7 +891,7 @@
 
 int printPlayer(SongData *songdata, double elapsedSeconds, PlayList *playlist)
 {
-        if (!uiEnabled || (hasPrintedPaused && isPaused()))
+        if (!uiEnabled)
         {
                 return 0;
         }
@@ -908,7 +908,7 @@
         if (preferredWidth <= 0 || preferredHeight <= 0)
                 return -1;
 
-        if (!printInfo)
+        if (!printPlaylist)
                 resetPlaylistDisplay = true;
 
         if (printKeyBindings)
@@ -920,7 +920,7 @@
                         saveCursorPosition();
                 }
         }
-        else if (printInfo)
+        else if (printPlaylist)
         {
                 if (refresh)
                 {
@@ -944,7 +944,7 @@
         }
         refresh = false;
         fflush(stdout);
-        hasPrintedPaused = true;
+
         return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/player.h new/kew-1.8.1/src/player.h
--- old/kew-1.7.3/src/player.h  2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/player.h  2023-11-29 01:42:25.000000000 +0100
@@ -17,7 +17,7 @@
 extern bool coverEnabled;
 extern bool uiEnabled;
 extern bool coverAnsi;
-extern bool printInfo;
+extern bool printPlaylist;
 extern bool printKeyBindings;
 extern bool visualizerEnabled;
 extern bool useThemeColors;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/playerops.c 
new/kew-1.8.1/src/playerops.c
--- old/kew-1.7.3/src/playerops.c       2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/playerops.c       2023-11-29 01:42:25.000000000 +0100
@@ -35,8 +35,6 @@
 volatile bool songLoading = false;
 GDBusConnection *connection = NULL;
 
-UserData userData;
-
 void updateLastSongSwitchTime()
 {
         clock_gettime(CLOCK_MONOTONIC, &start_time);
@@ -159,7 +157,7 @@
         {
                 emitStringPropertyChanged("LoopStatus", "None");
         }
-        if (printInfo)
+        if (printPlaylist)
                 refresh = true;
 }
 
@@ -192,7 +190,7 @@
         }
         loadedNextSong = false;
         nextSong = NULL;
-        if (printInfo)
+        if (printPlaylist)
                 refresh = true;
 }
 
@@ -269,6 +267,14 @@
 {
         if (seekAccumulatedSeconds != 0.0)
         {
+                if (currentSong != NULL)
+                {
+                        if (endsWith(currentSong->song.filePath, "ogg"))
+                        {
+                                return;
+                        }
+                }
+
                 setSeekElapsed(getSeekElapsed() + seekAccumulatedSeconds);
                 seekAccumulatedSeconds = 0.0;
                 calcElapsedTime();
@@ -286,6 +292,14 @@
 
 void seekForward()
 {
+        if (currentSong != NULL)
+        {
+                if (endsWith(currentSong->song.filePath, "ogg"))
+                {
+                        return;
+                }
+        }
+
         if (duration != 0.0)
         {
                 float step = 100 / numProgressBars;
@@ -296,6 +310,14 @@
 
 void seekBack()
 {
+        if (currentSong != NULL)
+        {
+                if (endsWith(currentSong->song.filePath, "ogg"))
+                {
+                        return;
+                }
+        }
+
         if (duration != 0.0)
         {
                 float step = 100 / numProgressBars;
@@ -328,28 +350,13 @@
 
 void assignLoadedData()
 {
-        if (usingSongDataA)
-        {
-                if (loadingdata.songdataB != NULL)
-                {
-                        userData.filenameB = 
loadingdata.songdataB->pcmFilePath;
-                        userData.songdataB = loadingdata.songdataB;
-                        if (hasBuiltinDecoder(loadingdata.songdataB->filePath))
-                                
prepareNextDecoder(loadingdata.songdataB->filePath);
-                        else if (endsWith(loadingdata.songdataB->filePath, 
"opus"))
-                                
prepareNextOpusDecoder(loadingdata.songdataB->filePath);
-                        else if (endsWith(loadingdata.songdataB->filePath, 
"ogg"))
-                                
prepareNextVorbisDecoder(loadingdata.songdataB->filePath);
-                }
-                else
-                        userData.filenameB = NULL;
-        }
-        else
+        if (loadingdata.loadA)
         {
                 if (loadingdata.songdataA != NULL)
                 {
                         userData.filenameA = 
loadingdata.songdataA->pcmFilePath;
                         userData.songdataA = loadingdata.songdataA;
+
                         if (hasBuiltinDecoder(loadingdata.songdataA->filePath))
                                 
prepareNextDecoder(loadingdata.songdataA->filePath);
                         else if (endsWith(loadingdata.songdataA->filePath, 
"opus"))
@@ -360,6 +367,23 @@
                 else
                         userData.filenameA = NULL;
         }
+        else
+        {
+                if (loadingdata.songdataB != NULL)
+                {
+                        userData.filenameB = 
loadingdata.songdataB->pcmFilePath;
+                        userData.songdataB = loadingdata.songdataB;
+
+                        if (hasBuiltinDecoder(loadingdata.songdataB->filePath))
+                                
prepareNextDecoder(loadingdata.songdataB->filePath);
+                        else if (endsWith(loadingdata.songdataB->filePath, 
"opus"))
+                                
prepareNextOpusDecoder(loadingdata.songdataB->filePath);
+                        else if (endsWith(loadingdata.songdataB->filePath, 
"ogg"))
+                                
prepareNextVorbisDecoder(loadingdata.songdataB->filePath);
+                }
+                else
+                        userData.filenameB = NULL;
+        }
 }
 
 void *songDataReaderThread(void *arg)
@@ -500,6 +524,7 @@
         }
 
         updateLastSongSwitchTime();
+
         skip();
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/songloader.c 
new/kew-1.8.1/src/songloader.c
--- old/kew-1.7.3/src/songloader.c      2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/songloader.c      2023-11-29 01:42:25.000000000 +0100
@@ -328,6 +328,11 @@
                 data->cover = NULL;
         }
 
+        if (existsInCache(tempCache, data->coverArtPath))
+        {
+                deleteFile(data->coverArtPath);
+        }
+
         free(data->red);
         free(data->green);
         free(data->blue);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundbuiltin.c 
new/kew-1.8.1/src/soundbuiltin.c
--- old/kew-1.7.3/src/soundbuiltin.c    2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundbuiltin.c    2023-11-29 01:42:25.000000000 +0100
@@ -151,6 +151,8 @@
                 ma_uint64 framesToRead = 0;
                 ma_decoder *firstDecoder = getFirstDecoder();
 
+                pthread_mutex_lock(&dataSourceMutex);                        
+
                 if (decoder == NULL || firstDecoder == NULL)
                         return;
 
@@ -159,6 +161,8 @@
                 ma_uint64 cursor;                
                 result = ma_data_source_get_cursor_in_pcm_frames(decoder, 
&cursor);
 
+                pthread_mutex_unlock(&dataSourceMutex);
+
                 if (((pPCMDataSource->totalFrames != 0 && cursor != 0 && 
cursor >= pPCMDataSource->totalFrames) || framesToRead == 0 || isSkipToNext() 
|| result != MA_SUCCESS) && !isEOFReached())
                 {
                         activateSwitch(pPCMDataSource);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundcommon.c 
new/kew-1.8.1/src/soundcommon.c
--- old/kew-1.7.3/src/soundcommon.c     2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundcommon.c     2023-11-29 01:42:25.000000000 +0100
@@ -2,6 +2,14 @@
 
 #define MAX_DECODERS 2
 
+/*
+
+soundcommon.c
+
+ Related to common functions for decoders / miniaudio implementations
+
+*/
+
 const char BUILTIN_EXTENSIONS[] = "\\.(mp3|flac|wav)$";
 
 bool repeatEnabled = false;
@@ -13,6 +21,8 @@
 double seekElapsed;
 _Atomic bool EOFReached = false;
 _Atomic bool switchReached = false;
+_Atomic bool readingFrames = false;
+pthread_mutex_t dataSourceMutex = PTHREAD_MUTEX_INITIALIZER;
 ma_device device = {0};
 ma_int32 *audioBuffer = NULL;
 ma_decoder *firstDecoder;
@@ -32,16 +42,6 @@
 int vorbisDecoderIndex = -1;
 bool doQuit = false;
 
-ma_libopus *getOpus()
-{
-        return &opus;
-}
-
-ma_libvorbis *getVorbis()
-{
-        return &vorbis;
-}
-
 enum AudioImplementation getCurrentImplementationType()
 {
         return currentImplementation;
@@ -273,6 +273,9 @@
 
         if (firstOpusDecoder != NULL)
         {
+                ma_data_source_base * base = (ma_data_source_base 
*)firstOpusDecoder;
+                base->pCurrent = NULL;
+                base->vtable = NULL;                   
                 ma_libopus_uninit(firstOpusDecoder, NULL);
                 free(firstOpusDecoder);
                 firstOpusDecoder = NULL;
@@ -659,7 +662,6 @@
                 ma_device_stop(&device);
                 paused = true;
         }
-        hasPrintedPaused = false;
 }
 
 void cleanupPlaybackDevice()
@@ -678,7 +680,6 @@
         {
                 ma_device_stop(&device);
                 paused = true;
-                hasPrintedPaused = false;
         }
         else if (paused)
         {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundcommon.h 
new/kew-1.8.1/src/soundcommon.h
--- old/kew-1.7.3/src/soundcommon.h     2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundcommon.h     2023-11-29 01:42:25.000000000 +0100
@@ -108,6 +108,7 @@
 };
 
 extern bool doQuit;
+extern pthread_mutex_t dataSourceMutex;
 
 ma_libopus *getOpus();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundgapless.c 
new/kew-1.8.1/src/soundgapless.c
--- old/kew-1.7.3/src/soundgapless.c    2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundgapless.c    2023-11-29 01:42:25.000000000 +0100
@@ -13,15 +13,20 @@
 */
 
 ma_context context;
-UserData *g_userData;
+
+UserData userData;
+
 PCMFileDataSource pcmDataSource;
 
-ma_result pcm_file_data_source_init(PCMFileDataSource *pPCMDataSource, 
UserData *pUserData)
+ma_result initFirstDatasource(PCMFileDataSource *pPCMDataSource, UserData 
*pUserData)
 {
         char *filePath = NULL;
 
         filePath = (pPCMDataSource->currentFileIndex == 0) ? 
pUserData->songdataA->filePath : pUserData->songdataB->filePath;
 
+        pPCMDataSource->pUserData = pUserData;
+        pPCMDataSource->currentPCMFrame = 0;
+
         if (hasBuiltinDecoder(filePath))
         {
                 prepareNextDecoder(filePath);
@@ -29,7 +34,6 @@
                 pPCMDataSource->format = first->outputFormat;
                 pPCMDataSource->channels = first->outputChannels;
                 pPCMDataSource->sampleRate = first->outputSampleRate;
-
                 ma_data_source_get_length_in_pcm_frames(first, 
&pPCMDataSource->totalFrames);
         }
         else if (endsWith(filePath, "opus"))
@@ -39,6 +43,8 @@
                 ma_channel channelMap[MA_MAX_CHANNELS];                
                 ma_libopus_ds_get_data_format(first, &pPCMDataSource->format, 
&pPCMDataSource->channels, &pPCMDataSource->sampleRate, channelMap, 
MA_MAX_CHANNELS);                
                 ma_data_source_get_length_in_pcm_frames(first, 
&pPCMDataSource->totalFrames);
+                ma_data_source_base *base = (ma_data_source_base*)first;
+                base->pCurrent = first;
                 first->pReadSeekTellUserData = pPCMDataSource;                
         }
         else if (endsWith(filePath, "ogg"))
@@ -48,24 +54,28 @@
                 ma_channel channelMap[MA_MAX_CHANNELS];              
                 ma_libvorbis_ds_get_data_format(first, 
&pPCMDataSource->format, &pPCMDataSource->channels, 
&pPCMDataSource->sampleRate, channelMap, MA_MAX_CHANNELS);
                 ma_data_source_get_length_in_pcm_frames(first, 
&pPCMDataSource->totalFrames);
+                ma_data_source_base *base = (ma_data_source_base*)first;
+                base->pCurrent = first;                
                 first->pReadSeekTellUserData = pPCMDataSource;                
         }
         else
         {
-                if (pPCMDataSource->fileA == NULL)
+                if ((pPCMDataSource->currentFileIndex == 0) && 
pPCMDataSource->fileA == NULL)
                 {
                         pPCMDataSource->filenameA = pUserData->filenameA;
                         pPCMDataSource->fileA = fopen(pUserData->filenameA, 
"rb");
                 }
+                else if ((pPCMDataSource->currentFileIndex == 1) && 
pPCMDataSource->fileB == NULL)
+                {
+                        pPCMDataSource->filenameB = pUserData->filenameB;
+                        pPCMDataSource->fileB = fopen(pUserData->filenameB, 
"rb");
+                }
 
                 pPCMDataSource->format = SAMPLE_FORMAT;
                 pPCMDataSource->channels = CHANNELS;
                 pPCMDataSource->sampleRate = SAMPLE_RATE;
         }
 
-        pPCMDataSource->pUserData = pUserData;
-        pPCMDataSource->currentPCMFrame = 0;
-
         return MA_SUCCESS;
 }
 
@@ -74,7 +84,7 @@
         ma_result result;
 
         ma_data_source_uninit(&pcmDataSource);
-        pcm_file_data_source_init(&pcmDataSource, userData);
+        initFirstDatasource(&pcmDataSource, userData);
 
         pcmDataSource.base.vtable = vtable;
 
@@ -103,37 +113,12 @@
         createDevice(userData, device, context, vtable, pcm_on_audio_frames);
 }
 
-ma_result vorbis_data_source_init(PCMFileDataSource *pPCMDataSource, 
ma_libvorbis *vorbis, char *filePath)
-{
-        ma_format format;
-        ma_uint32 channels;
-        ma_uint32 sampleRate;
-        ma_channel channelMap[MA_MAX_CHANNELS];
-
-        ma_libvorbis_init_file(filePath, NULL, NULL, vorbis);
-        ma_libvorbis_ds_get_data_format(vorbis, &format, &channels, 
&sampleRate, channelMap, MA_MAX_CHANNELS);
-        pPCMDataSource->sampleRate = sampleRate;
-        pPCMDataSource->channels = channels;
-        pPCMDataSource->format = format;
-
-        vorbis->format = format;
-        vorbis->onRead = ma_libvorbis_read_pcm_frames_wrapper;
-        vorbis->onSeek = ma_libvorbis_seek_to_pcm_frame_wrapper;
-        vorbis->onTell = ma_libvorbis_get_cursor_in_pcm_frames_wrapper;
-        vorbis->pReadSeekTellUserData = pPCMDataSource;
-
-        return MA_SUCCESS;
-}
-
 void vorbis_createAudioDevice(UserData *userData, ma_device *device, 
ma_context *context, ma_data_source_vtable *vtable)
 {
         ma_result result;
 
-        pcm_file_data_source_init(&pcmDataSource, userData);
-        char *filePath = pcmDataSource.currentFileIndex == 0 ? 
userData->songdataA->filePath : userData->songdataB->filePath;
+        initFirstDatasource(&pcmDataSource, userData);
         ma_libvorbis *vorbis = getFirstVorbisDecoder();
-        vorbis_data_source_init(&pcmDataSource, vorbis, filePath);
-
         ma_device_config deviceConfig = 
ma_device_config_init(ma_device_type_playback);
 
         deviceConfig.playback.format = vorbis->format;
@@ -158,36 +143,12 @@
         }
 }
 
-ma_result opus_data_source_init(PCMFileDataSource *pPCMDataSource, ma_libopus 
*opus, char *filePath)
-{
-        ma_format format;
-        ma_uint32 channels;
-        ma_uint32 sampleRate;
-        ma_channel channelMap[MA_MAX_CHANNELS];
-
-        ma_libopus_init_file(filePath, NULL, NULL, opus);
-        ma_libopus_ds_get_data_format(opus, &format, &channels, &sampleRate, 
channelMap, MA_MAX_CHANNELS);
-        pPCMDataSource->sampleRate = sampleRate;
-        pPCMDataSource->channels = channels;
-        pPCMDataSource->format = format;
-
-        opus->format = format;
-        opus->onRead = ma_libopus_read_pcm_frames_wrapper;
-        opus->onSeek = ma_libopus_seek_to_pcm_frame_wrapper;
-        opus->onTell = ma_libopus_get_cursor_in_pcm_frames_wrapper;
-        opus->pReadSeekTellUserData = pPCMDataSource;
-
-        return MA_SUCCESS;
-}
-
 void opus_createAudioDevice(UserData *userData, ma_device *device, ma_context 
*context, ma_data_source_vtable *vtable)
 {
         ma_result result;
 
-        pcm_file_data_source_init(&pcmDataSource, userData);
-        char *filePath = pcmDataSource.currentFileIndex == 0 ? 
userData->songdataA->filePath : userData->songdataB->filePath;
-        ma_libopus *opus = getFirstOpusDecoder();
-        opus_data_source_init(&pcmDataSource, opus, filePath);        
+        initFirstDatasource(&pcmDataSource, userData);
+        ma_libopus *opus = getFirstOpusDecoder();  
 
         ma_device_config deviceConfig = 
ma_device_config_init(ma_device_type_playback);
 
@@ -217,14 +178,27 @@
 {
         enum AudioImplementation currentImplementation = 
getCurrentImplementationType();
 
-        if (g_userData->currentSongData == NULL)
+        if (pcmDataSource.currentFileIndex == 0)
+        {
+                userData.currentSongData = userData.songdataA;
+        }
+        else
+        {
+                userData.currentSongData = userData.songdataB;
+        }
+
+        if (userData.currentSongData == NULL)
+        {
+                setEOFNotReached();
                 return;
+        }
 
-        char *filePath = strdup(g_userData->currentSongData->filePath);
+        char *filePath = strdup(userData.currentSongData->filePath);
 
         if (filePath == NULL || filePath[0] == '\0' || filePath[0] == '\r')
         {
                 free(filePath);
+                setEOFNotReached();
                 return;
         }
 
@@ -244,14 +218,23 @@
                 if (isRepeatEnabled() || !(sameFormat && currentImplementation 
== BUILTIN))
                 {
                         setImplSwitchReached();
+
+                        pthread_mutex_lock(&dataSourceMutex);
+
                         setCurrentImplementationType(BUILTIN);
+                        
                         resetDecoders();
                         resetVorbisDecoders();
                         resetOpusDecoders();
                         resetAudioBuffer();
+
                         cleanupPlaybackDevice();
+
+                        builtin_createAudioDevice(&userData, getDevice(), 
&context, &builtin_file_data_source_vtable);
+
+                        pthread_mutex_unlock(&dataSourceMutex);
+
                         setImplSwitchNotReached();                        
-                        builtin_createAudioDevice(g_userData, getDevice(), 
&context, &builtin_file_data_source_vtable);
                 }
         }
         else if (endsWith(filePath, "opus"))
@@ -283,14 +266,23 @@
                 else
                 {
                         setImplSwitchReached();
-                        setCurrentImplementationType(OPUS);                    
  
+
+                        pthread_mutex_lock(&dataSourceMutex);
+
+                        setCurrentImplementationType(OPUS); 
+
                         resetDecoders();
                         resetVorbisDecoders();
                         resetOpusDecoders();
                         resetAudioBuffer();
+
                         cleanupPlaybackDevice();
-                        setImplSwitchNotReached();
-                        opus_createAudioDevice(g_userData, getDevice(), 
&context, &pcm_file_data_source_vtable);
+
+                        opus_createAudioDevice(&userData, getDevice(), 
&context, &pcm_file_data_source_vtable);
+
+                        pthread_mutex_unlock(&dataSourceMutex);
+
+                        setImplSwitchNotReached();                        
                 }
         }
         else if (endsWith(filePath, "ogg"))
@@ -321,15 +313,24 @@
                 }
                 else
                 {
-                        setImplSwitchReached();                        
+                        setImplSwitchReached();
+                        
+                        pthread_mutex_lock(&dataSourceMutex);
+
                         setCurrentImplementationType(VORBIS);
+
                         resetDecoders();
                         resetVorbisDecoders();
                         resetOpusDecoders();
                         resetAudioBuffer();
-                        cleanupPlaybackDevice();
+
+                        cleanupPlaybackDevice(); 
+                                           
+                        vorbis_createAudioDevice(&userData, getDevice(), 
&context, &pcm_file_data_source_vtable);
+
+                        pthread_mutex_unlock(&dataSourceMutex);
+
                         setImplSwitchNotReached();                        
-                        vorbis_createAudioDevice(g_userData, getDevice(), 
&context, &pcm_file_data_source_vtable);
                 }
         }
         else
@@ -337,14 +338,20 @@
                 if (isRepeatEnabled() || currentImplementation != PCM)
                 {
                         setImplSwitchReached();
+
+                        pthread_mutex_lock(&dataSourceMutex);
+
                         setCurrentImplementationType(PCM);
                         resetDecoders();
                         resetVorbisDecoders();
                         resetOpusDecoders();
                         resetAudioBuffer();
-                        cleanupPlaybackDevice();
+                        cleanupPlaybackDevice();                       
+                        pcm_createAudioDevice(&userData, getDevice(), 
&context, &pcm_file_data_source_vtable);
+
+                        pthread_mutex_unlock(&dataSourceMutex);
+
                         setImplSwitchNotReached();                        
-                        pcm_createAudioDevice(g_userData, getDevice(), 
&context, &pcm_file_data_source_vtable);
                 }
         }
         free(filePath);
@@ -358,7 +365,6 @@
 
 void createAudioDevice(UserData *userData)
 {
-        g_userData = userData;
         ma_context_init(NULL, 0, NULL, &context);
         switchAudioImplementation();
 }
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundgapless.h 
new/kew-1.8.1/src/soundgapless.h
--- old/kew-1.7.3/src/soundgapless.h    2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundgapless.h    2023-11-29 01:42:25.000000000 +0100
@@ -6,6 +6,7 @@
 #include <stdbool.h>
 #include <unistd.h>
 #include <stdatomic.h>
+#include <pthread.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/wait.h>
@@ -32,6 +33,8 @@
 } UserData;
 #endif
 
+extern UserData userData;
+
 void setDecoders(bool usingA, char *filePath);
 
 void createAudioDevice(UserData *userData);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundopus.c 
new/kew-1.8.1/src/soundopus.c
--- old/kew-1.7.3/src/soundopus.c       2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundopus.c       2023-11-29 01:42:25.000000000 +0100
@@ -63,7 +63,7 @@
                         ma_uint64 seekPercent = getSeekPercentage();
                         if (seekPercent >= 100.0)
                                 seekPercent = 100.0;
-                        ma_uint64 targetFrame = (totalFrames * seekPercent) / 
100;
+                        ma_uint64 targetFrame = (totalFrames * seekPercent) / 
100 - 1; // Remove one frame or we get invalid args if we send in totalframes
 
                         // Set the read pointer for the decoder
                         ma_result seekResult = 
ma_libopus_seek_to_pcm_frame(decoder, targetFrame);
@@ -82,12 +82,22 @@
                 ma_result result;
                 ma_uint64 remainingFrames = frameCount - framesRead;
                 ma_libopus *firstDecoder = getFirstOpusDecoder();
+                              
+                pthread_mutex_lock(&dataSourceMutex);
+
+                if (firstDecoder == NULL)
+                {
+                        return;
+                }
+
                 result = ma_data_source_read_pcm_frames(firstDecoder, 
(ma_int32 *)pFramesOut + framesRead * pPCMDataSource->channels, 
remainingFrames, &framesToRead);
 
                 ma_uint64 cursor;
 
                 ma_data_source_get_cursor_in_pcm_frames(decoder, &cursor);
 
+                pthread_mutex_unlock(&dataSourceMutex);
+
                 if (((cursor != 0 && cursor >= pPCMDataSource->totalFrames) || 
framesToRead == 0 || isSkipToNext() || result != MA_SUCCESS) && !isEOFReached())
                 {
                         activateSwitch(pPCMDataSource);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundpcm.c new/kew-1.8.1/src/soundpcm.c
--- old/kew-1.7.3/src/soundpcm.c        2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundpcm.c        2023-11-29 01:42:25.000000000 +0100
@@ -68,11 +68,6 @@
 
                 if (currentFile != NULL)
                         bytesRead = (ma_uint32)fread((char *)pFramesOut + 
(framesRead * bytesPerFrame), 1, bytesToRead, currentFile);
-                else if (pPCMDataSource->pUserData->currentSongData == NULL ||
-                         
hasBuiltinDecoder(pPCMDataSource->pUserData->currentSongData->filePath) ||
-                         
(endsWith(pPCMDataSource->pUserData->currentSongData->filePath, "opus")) ||
-                         
(endsWith(pPCMDataSource->pUserData->currentSongData->filePath, "ogg")))
-                        return;
 
                 // If file is empty, skip
                 if ((bytesRead == 0 || isSkipToNext()) && !isEOFReached())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/soundvorbis.c 
new/kew-1.8.1/src/soundvorbis.c
--- old/kew-1.7.3/src/soundvorbis.c     2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/soundvorbis.c     2023-11-29 01:42:25.000000000 +0100
@@ -81,7 +81,18 @@
                 ma_uint64 framesToRead = 0;
                 ma_result result;
                 ma_uint64 remainingFrames = frameCount - framesRead;
-                result = 
ma_data_source_read_pcm_frames(getFirstVorbisDecoder(), (ma_int32 *)pFramesOut 
+ framesRead * pPCMDataSource->channels, remainingFrames, &framesToRead);
+                ma_libvorbis *firstDecoder = getFirstVorbisDecoder();
+
+                pthread_mutex_lock(&dataSourceMutex);
+
+                if (firstDecoder == NULL)
+                {
+                        return;
+                }
+
+                result = ma_data_source_read_pcm_frames(firstDecoder, 
(ma_int32 *)pFramesOut + framesRead * pPCMDataSource->channels, 
remainingFrames, &framesToRead);
+                
+                pthread_mutex_unlock(&dataSourceMutex);                
 
                 if ((getPercentageElapsed() >= 1.0 || isSkipToNext() || result 
!= MA_SUCCESS) &&
                     !isEOFReached())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/visuals.c new/kew-1.8.1/src/visuals.c
--- old/kew-1.7.3/src/visuals.c 2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/visuals.c 2023-11-29 01:42:25.000000000 +0100
@@ -13,6 +13,8 @@
 float magnitudeCeil = 120;
 float alpha = 0.2;
 float lastMax = 60;
+bool unicodeSupport = false;
+
 /*
 
 visuals.c
@@ -25,6 +27,14 @@
 float magnitudeBuffer[MAX_BUFFER_SIZE] = {0.0f};
 float lastMagnitudes[MAX_BUFFER_SIZE] = {0.0f};
 
+void initVisuals()
+{
+        unicodeSupport = false;
+        char *locale = setlocale(LC_ALL, "");
+        if (locale != NULL)
+                unicodeSupport = true;        
+}
+
 void printBlankSpaces(int numSpaces)
 {
         for (int i = 0; i < numSpaces; i++)
@@ -119,7 +129,7 @@
         int beat = detectBeats(magnitudes, width);
         if (beat > 0)
         {
-               jumpFactor = jumpAmount;
+                jumpFactor = jumpAmount;
         }
 
         for (int i = 0; i < width; i++)
@@ -130,7 +140,8 @@
                 {
                         exponent = 2.0;
                 }
-                else {
+                else
+                {
                         exponent = 1.0;
                 }
                 float normalizedMagnitude = magnitudes[i] / maxMagnitude;
@@ -182,7 +193,7 @@
         int j = 0;
 
         for (int i = 0; i < bufferSize; i++)
-        {                
+        {
                 ma_int32 sample = audioBuffer[i];
 
                 float normalizedSample;
@@ -224,12 +235,12 @@
                 {
                         // Unsupported bit depth
                         return;
-                }                
+                }
 
                 if (bitDepth == 32)
                 {
                         if (i % 3 != 0)
-                        {                                
+                        {
                                 continue;
                         }
                 }
@@ -266,6 +277,29 @@
         updateMagnitudes(height, numBars, maxMagnitude, magnitudes);
 }
 
+wchar_t *getUpwardMotionChar(int level) {
+    switch (level) {
+        case 0:
+            return L" ";
+        case 1:
+            return L"▁";
+        case 2:
+            return L"▂";
+        case 3:
+            return L"▃";
+        case 4:
+            return L"▄";
+        case 5:
+            return L"▅";
+        case 6:
+            return L"▆";
+        case 7:
+            return L"▇";
+        default:
+            return L"█";
+    }
+}
+
 void calcSpectrum(int height, int numBars, fftwf_complex *fftInput, 
fftwf_complex *fftOutput, float *magnitudes, fftwf_plan plan)
 {
 
@@ -292,7 +326,7 @@
                 case ma_format_s24:
                         bitDepth = 24;
                         break;
-                
+
                 case ma_format_f32:
                 case ma_format_s32:
                         bitDepth = 32;
@@ -330,6 +364,8 @@
         printf("\n");
         clearRestOfScreen();
 
+        PixelData tmp;
+
         for (int j = height; j > 0; j--)
         {
                 printf("\r");
@@ -338,33 +374,46 @@
                 {
                         if (!useProfileColors)
                         {
-                                if (j == height)
-                                {
-                                        color = increaseLuminosity(color, 100);
-                                        printf("\033[38;2;%d;%d;%dm", color.r, 
color.g, color.b);
-                                }
-                                else
-                                {
-                                        color = decreaseLuminosity(color, 100 
/ height);
-                                        printf("\033[38;2;%d;%d;%dm", color.r, 
color.g, color.b);
-                                }
+                                tmp = increaseLuminosity(color, round(j * 
height * 2));
+                                printf("\033[38;2;%d;%d;%dm", tmp.r, tmp.g, 
tmp.b);
                         }
                 }
                 else
                 {
                         setDefaultTextColor();
                 }
-                for (int i = 0; i < width; i++)
+                if (isPaused())
                 {
-                        if (j >= 0)
+                        for (int i = 0; i < width; i++)
                         {
-                                if ((int)round(magnitudes[i]) >= j)
-                                {
-                                        printf(" █");
-                                }
-                                else
+                                printf("  ");
+                        }                        
+                }
+                else
+                {
+                        for (int i = 0; i < width; i++)
+                        {
+                                if (j >= 0)
                                 {
-                                        printf("  ");
+                                        if (magnitudes[i] >= j)
+                                        {
+                                                if (unicodeSupport)
+                                                {
+                                                        printf(" %S", 
getUpwardMotionChar(10));
+                                                }       
+                                                else {
+                                                        printf(" █");
+                                                }
+                                        }
+                                        else if (magnitudes[i] + 1 >= j && 
unicodeSupport)
+                                        {
+                                                int firstDecimalDigit = 
(int)(fmod(magnitudes[i] * 10, 10));
+                                                printf(" %S", 
getUpwardMotionChar(firstDecimalDigit));                                   
+                                        }
+                                        else
+                                        {
+                                                printf("  ");
+                                        }
                                 }
                         }
                 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-1.7.3/src/visuals.h new/kew-1.8.1/src/visuals.h
--- old/kew-1.7.3/src/visuals.h 2023-11-25 23:57:24.000000000 +0100
+++ new/kew-1.8.1/src/visuals.h 2023-11-29 01:42:25.000000000 +0100
@@ -4,10 +4,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
+#include <locale.h>
 #include "soundgapless.h"
 #include "term.h"
 #include "write_ascii.h"
 
+void initVisuals();
+
 void drawSpectrumVisualizer(int height, int width, PixelData c);
 
 PixelData increaseLuminosity(PixelData pixel, int amount);

Reply via email to