Example #1
0
 ///
 /// Adds the info for this local track-on-disk to the database
 ///
 public void Add( PlayableData newData )
 {
     lock (_serializer)
      {
     _database.Add( newData );
      }
 }
Example #2
0
 ///
 /// Add a track to the end of the playlist. Duh. :)
 ///
 void _PlaylistAppend( PlayableData trackData )
 {
     _playQueueMutex.WaitOne();
      try
      {
     _playQueue.Add( trackData );
      }
      finally
      {
     _playQueueMutex.ReleaseMutex();
      }
 }
Example #3
0
        ///
        /// This is sort of random. We sometimes play tracks even if
        /// they suck.
        ///
        /// \return true if this track doesn't suck too much
        ///
        bool _WantToPlayTrack( PlayableData info )
        {
            int nUsers = _controllers.Count;
             uint trackKey = info.key;

             // Now, decide whether we are going to actually PLAY this
             // track.  While we're at it, delete people who have abandoned
             // us or closed their browsers.
             double unSuckProb = 1.0;  // (probability that it will play)
             double moodProb = 1.0;  // Composite mood threshold
             DateTime now = DateTime.Now; // cached for speed?

             // make a copy of the hash table keys, cause otherwise we can't
             // delete things:
             object [] keys = new object[_controllers.Count];
             _controllers.Keys.CopyTo( keys, 0 );

             // This is a decimation playlist, so it has to pass everybody's
             // test before it will be played.  If you have too many
             // contributors, you will end up with mediocre crap only.
             // The only way around this is to either listen to songs you don't
             // like or to limit the number of contributors.

             // Assuming this song has to pass everybody's tests, calculate
             // the overall probablility and just test once (conserves randomness)

             _Trace( "Merging contributor opinions..." );
             for (int i = 0; i < keys.Length; i++)
             {
            uint key = (uint)keys[i];
            Contributor contrib = (Contributor)_controllers[key];

            // Check to see if this user has timed out.
            if (now - contrib.lastPing > CONTRIBUTOR_TIMEOUT)
            {
               _Trace( "User timed out, removing: " + contrib.user.name );
               _controllers.Remove( key );
               -- nUsers;
               Debug.Assert( nUsers >= 0, "removed more users than existed?" );
               continue;        // ** SKIP THIS LOGGED OUT DEADBEAT **
            }
            _Trace( " - " + contrib.user.name );

            double userSuck = (double)_database.GetSuck( contrib.user.id,
                                                         trackKey );
            userSuck /= 10000.0; // convert to probability

            unSuckProb *= 1.0 - userSuck; // combine max suck amounts

            double userMood = _database.GetAppropriate( contrib.user.id,
                                                        contrib.mood.id,
                                                        trackKey );

            userMood /= 10000.0;

            moodProb *= userMood;
             }

             if (0 >= nUsers)       // Nobody exists, just play it.
            return true;

             // Convert it back to an "int"
             int suckProb = (int)((1.0 - unSuckProb) * 10000.0);
             moodProb *= 10000.0;

             _Trace( "MOOD_PROB: " + moodProb + " SUCK_PROB: " + suckProb );

             // If suckThresh is less than the suck amount, we don't play it.
             // Sort of like a saving throw. Save Vs. Suck.

             uint suckThresh = (uint)_cheapRandom.Next( 01000, 09000 );
             if (suckProb > suckThresh)
             {
            _Trace( " Rejected. suckProb:" + suckProb
                    + " suckThresh:" + suckThresh );

            info.evaluation = TrackEvaluation.SUCK_TOO_MUCH;
            return false;       // methinks it sucketh too much
             }

             uint moodThresh = (uint)_cheapRandom.Next( 01200, 08800 );
             if (moodProb < moodThresh)
             {
            _Trace( " Rejected. moodProb:" + moodProb
                    + " moodThresh:" + moodThresh );

            info.evaluation = TrackEvaluation.WRONG_MOOD;
            return false;       // not in the mood
             }

             _Trace( String.Format(
                    " Accepted. suckProb:{0}, suckThresh:{1}, moodProb:{2}, moodThresh{3}",
                    suckProb, suckThresh, moodProb, moodThresh ));

             info.evaluation = TrackEvaluation.ALL_GOOD;
             return true;           // good enough
        }
        ///
        /// Updates the database info for a file. Assumes the file is an
        /// MP3 file.
        ///
        /// \todo Create a pluggable interface to extract the file info
        ///   from various file types, not just mp3
        ///
        void _UpdateMP3FileInfo( string path, IBackend engine )
        {
            // Get ID3 tags from the file

             ID3v2 tag = new ID3v2( path, false );
             if (!tag.isValid)
             {
            _Trace( "Note: No id3v2 tag found in file: '"
                    + path
                    + "'" );

            return;
             }

             if ((null == tag.tit2) || (tag.tit2.Length == 0))
             {
            // Match anything after the last forward/backslash
            string basename = Path.GetFileName( path );
            Debug.Assert( null != basename, "All files have names!" );
            Debug.Assert( basename.Length > 0, "All files have names!" );
            _Trace( "Song title is empty, using file name: '"
                    + basename
                    + "'" );

            tag.tit2 = basename;
             }

             string genre = tag.DefaultGenre;
             if (null == genre)
            genre = "unknown";

             if (engine.EntryExists( path ))
             {
            engine.FileIsNotMissing( path );
             }
             else
             {
            // Oh god, the noise, the noise! Just comment when something interesting
            // heppens, OK?
            // _Trace( "adding '" + path + "'" );

            PlayableData data = new PlayableData();
            data.filePath = path;

            if (tag.tpe1 == null)
               data.artist = "";
            else
               data.artist = tag.tpe1;

            if (tag.talb == null)
               data.album = "";
            else
               data.album = tag.talb;

            if (tag.tit2 == null) // no title, maybe check tit1 and tit3?
               data.title = "";
            else
               data.title = tag.tit2;

            data.track = tag.trackIndex;
            data.genre = genre;
            data.lengthInSeconds = 0; // unknown, ID3 tag doesn't know
            engine.Add( data );
             }
        }