~ubuntu-branches/ubuntu/precise/guayadeque/precise

« back to all changes in this revision

Viewing changes to src/.svn/text-base/MusicDns.cpp.svn-base

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2011-05-14 15:08:03 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110514150803-8b5evqetnaj35j34
Tags: 0.3.1~dfsg0-1
* New upstream release.
* Strip wxsqlite3 stuff out of upstream's tarballs.
* Update get-orig-source target in debian/rules.
* Update gbp config file.
* Bump Standards.
* Build-depend on libwxsqlite3-2.8-dev
* Enable parallel builds.
* Link binaries against the system-wide copy of wxsqlite3.
* Point sources to the correct wxcurl's headers location.
* Update copyright file as per DEP-5
* Improve debian/watch to handle the ~dfsg\d* suffix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -------------------------------------------------------------------------------- //
2
 
//      Copyright (C) 2008-2010 J.Rios
3
 
//      anonbeat@gmail.com
4
 
//
5
 
//    This Program is free software; you can redistribute it and/or modify
6
 
//    it under the terms of the GNU General Public License as published by
7
 
//    the Free Software Foundation; either version 2, or (at your option)
8
 
//    any later version.
9
 
//
10
 
//    This Program is distributed in the hope that it will be useful,
11
 
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 
//    GNU General Public License for more details.
14
 
//
15
 
//    You should have received a copy of the GNU General Public License
16
 
//    along with this program; see the file LICENSE.  If not, write to
17
 
//    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
//    http://www.gnu.org/copyleft/gpl.html
19
 
//
20
 
// -------------------------------------------------------------------------------- //
21
 
#include "MusicDns.h"
22
 
 
23
 
#include "Commands.h"
24
 
#include "curl/http.h"
25
 
#include "MusicBrainz.h"
26
 
#include "Utils.h"
27
 
#include "Version.h"
28
 
 
29
 
#define guMUSICDNS_CLIENT_ID    "ca3d48c7383db1dcf6dccd1f0cab26e5"
30
 
#define guMUSICDNS_BASEURL      "http://ofa.musicdns.org/ofa/1/track"
31
 
 
32
 
#define guMUSICDNS_REQSTR_FP    "cid=%s&cvr=%s&fpt=%s&rmd=%d&" \
33
 
                                "brt=%d&fmt=%s&dur=%ld&art=%s&" \
34
 
                                "ttl=%s&alb=%s&tnm=%d&gnr=%s&" \
35
 
                                "yrr=%s&enc=UTF-8&\r\n"
36
 
 
37
 
#define guMUSICDNS_REQSTR_PUID  "cid=%s&cvr=%s&pid=%s&rmd=%d&" \
38
 
                                "brt=%d&fmt=%s&dur=%ld&art=%s&" \
39
 
                                "ttl=%s&alb=%s&tnm=%d&gnr=%s&" \
40
 
                                "yrr=%s&enc=UTF-8&\r\n"
41
 
 
42
 
extern "C" {
43
 
 
44
 
//#include <gstofa.h>
45
 
// From gstofa.h
46
 
#define GST_TAG_OFA_FINGERPRINT "ofa-fingerprint"
47
 
 
48
 
//// -------------------------------------------------------------------------------- //
49
 
//void list_tags( const GstTagList * list, const gchar * tag, gpointer user_data )
50
 
//{
51
 
//    printf( "Tag: %s\n", tag );
52
 
//}
53
 
 
54
 
// -------------------------------------------------------------------------------- //
55
 
static gboolean gst_bus_async_callback( GstBus * bus, GstMessage * message, guMusicDnsThread * pobj )
56
 
{
57
 
    //guLogMessage( wxT( "Got gstreamer message %u" ), GST_MESSAGE_TYPE( message ) );
58
 
    switch( GST_MESSAGE_TYPE( message ) )
59
 
    {
60
 
        case GST_MESSAGE_ERROR :
61
 
        {
62
 
            GError * err;
63
 
            gchar * debug;
64
 
            gst_message_parse_error( message, &err, &debug );
65
 
            guLogError( wxT( "Gstreamer error '%s'" ), wxString( err->message, wxConvUTF8 ).c_str() );
66
 
            g_error_free( err );
67
 
            g_free( debug );
68
 
 
69
 
            pobj->Stop();
70
 
            break;
71
 
        }
72
 
 
73
 
        case GST_MESSAGE_STATE_CHANGED:
74
 
        {
75
 
            GstState oldstate, newstate, pendingstate;
76
 
            gst_message_parse_state_changed( message, &oldstate, &newstate, &pendingstate );
77
 
            //guLogMessage( wxT( "State changed... %u  %u  %u" ), oldstate, newstate, pendingstate );
78
 
            break;
79
 
        }
80
 
 
81
 
//        case GST_MESSAGE_BUFFERING :
82
 
//        {
83
 
//            guLogMessage( wxT( "Buffering..." ) );
84
 
//            break;
85
 
//        }
86
 
 
87
 
        case GST_MESSAGE_EOS :
88
 
        {
89
 
          //guLogMessage( wxT( "EOS Detected..." ) );
90
 
          pobj->Stop();
91
 
          break;
92
 
        }
93
 
 
94
 
        case GST_MESSAGE_TAG :
95
 
        {
96
 
            /* The stream discovered new tags. */
97
 
            GstTagList * tags;
98
 
            gchar * fingerprint = NULL;
99
 
            /* Extract from the message the GstTagList.
100
 
            * This generates a copy, so we must remember to free it.*/
101
 
            gst_message_parse_tag( message, &tags );
102
 
 
103
 
            //gst_tag_list_foreach( tags, ( GstTagForeachFunc ) list_tags, NULL );
104
 
 
105
 
            /* Extract the title and artist tags - if they exist */
106
 
            gst_tag_list_get_string( tags, GST_TAG_OFA_FINGERPRINT, &fingerprint );
107
 
 
108
 
            if( fingerprint )
109
 
            {
110
 
                //guLogMessage( wxT( "Gstreamer got fingerprint '%s'" ), wxString( fingerprint, wxConvUTF8 ).c_str() );
111
 
                pobj->SetFingerprint( fingerprint );
112
 
                g_free( fingerprint );
113
 
            }
114
 
 
115
 
            /* Free the tag list */
116
 
            gst_tag_list_free( tags );
117
 
            break;
118
 
        }
119
 
 
120
 
        default:
121
 
            break;
122
 
    }
123
 
 
124
 
    return TRUE;
125
 
}
126
 
 
127
 
// -------------------------------------------------------------------------------- //
128
 
static void on_pad_added( GstElement * decodebin, GstPad * pad, gboolean last, GstElement * conv )
129
 
{
130
 
  GstCaps * caps;
131
 
  GstStructure * str;
132
 
  GstPad * convpad;
133
 
//  GstElement * conv;
134
 
//  conv = ( GstElemet * ) data;
135
 
 
136
 
//  guLogMessage( wxT( "New pad created..." ) );
137
 
 
138
 
  convpad = gst_element_get_pad( conv, "sink" );
139
 
 
140
 
  /* check media type */
141
 
  caps = gst_pad_get_caps( pad );
142
 
  str = gst_caps_get_structure( caps, 0 );
143
 
  if( !g_strrstr( gst_structure_get_name( str ), "audio" ) )
144
 
  {
145
 
    gst_caps_unref( caps );
146
 
    gst_object_unref( convpad );
147
 
    return;
148
 
  }
149
 
  gst_caps_unref( caps );
150
 
 
151
 
//  guLogMessage( wxT( "Linked decoder and converter..." ) );
152
 
  /* link'n'play */
153
 
  gst_pad_link( pad, convpad );
154
 
}
155
 
 
156
 
 
157
 
}
158
 
 
159
 
// -------------------------------------------------------------------------------- //
160
 
// guMusicDnsThread
161
 
// -------------------------------------------------------------------------------- //
162
 
guMusicDnsThread::guMusicDnsThread( guMusicDns * musicdns, const wxChar * filename )
163
 
{
164
 
  wxASSERT( musicdns );
165
 
 
166
 
  //guLogMessage( wxT( "guMusicDnsThread..." ) );
167
 
  m_MusicDns = musicdns;
168
 
  m_FileName = wxString( filename );
169
 
  m_Running = false;
170
 
  int Error = guMDNS_STATUS_ERROR_GSTREAMER;
171
 
 
172
 
  m_Pipeline = gst_pipeline_new( "guPipeline" );
173
 
  if( GST_IS_ELEMENT( m_Pipeline ) )
174
 
  {
175
 
    GstElement * src;
176
 
    src = gst_element_factory_make( "filesrc", "guSource" );
177
 
    if( GST_IS_ELEMENT( src ) )
178
 
    {
179
 
      g_object_set( G_OBJECT( src ), "location", ( const char * ) m_FileName.mb_str(), NULL );
180
 
      GstElement * dec;
181
 
      dec = gst_element_factory_make( "decodebin", "guDecoder" );
182
 
      if( GST_IS_ELEMENT( dec ) )
183
 
      {
184
 
        GstElement * conv;
185
 
        conv = gst_element_factory_make( "audioconvert", "guConverter" );
186
 
        if( GST_IS_ELEMENT( conv ) )
187
 
        {
188
 
          GstElement * ofa;
189
 
          ofa = gst_element_factory_make( "ofa", "guOFA" );
190
 
          if( GST_IS_ELEMENT( ofa ) )
191
 
          {
192
 
            GstElement * fake;
193
 
            fake = gst_element_factory_make( "fakesink", "guFakeSink" );
194
 
            g_object_set( G_OBJECT( fake ), "sync", 0, NULL );
195
 
            if( GST_IS_ELEMENT( fake ) )
196
 
            {
197
 
              gst_bin_add_many( GST_BIN( m_Pipeline ), src, dec, conv, ofa, fake, NULL );
198
 
 
199
 
              GstBus * bus = gst_pipeline_get_bus( GST_PIPELINE( m_Pipeline ) );
200
 
              gst_bus_add_watch( bus, ( GstBusFunc ) gst_bus_async_callback, this );
201
 
              gst_object_unref( G_OBJECT( bus ) );
202
 
 
203
 
              if( gst_element_link( src, dec ) )
204
 
              {
205
 
                g_signal_connect( dec, "new-decoded-pad", G_CALLBACK( on_pad_added ), conv );
206
 
 
207
 
                if( gst_element_link_many( conv, ofa, fake, NULL ) )
208
 
                {
209
 
                  gst_element_set_state( m_Pipeline, GST_STATE_PAUSED );
210
 
 
211
 
                  //guLogMessage( wxT( "Created the pipeline..." ) );
212
 
 
213
 
                  if( Create() == wxTHREAD_NO_ERROR )
214
 
                  {
215
 
                    SetPriority( WXTHREAD_DEFAULT_PRIORITY - 30 );
216
 
                    Run();
217
 
                    return;
218
 
                  }
219
 
                  else
220
 
                  {
221
 
                    Error = guMDNS_STATUS_ERROR_THREAD;
222
 
                  }
223
 
                }
224
 
                else
225
 
                {
226
 
                  guLogError( wxT( "Error linking the objects conv, ofa, fake" ) );
227
 
                }
228
 
              }
229
 
              else
230
 
              {
231
 
                guLogError( wxT( "Error linking the objects src, dec" ) );
232
 
              }
233
 
              gst_object_unref( fake );
234
 
            }
235
 
            else
236
 
            {
237
 
              guLogError( wxT( "Error creating the MusicDns fakeout" ) );
238
 
            }
239
 
            gst_object_unref( ofa );
240
 
          }
241
 
          else
242
 
          {
243
 
            guLogError( wxT( "Error creating the MusicDns ofa" ) );
244
 
          }
245
 
          gst_object_unref( conv );
246
 
        }
247
 
        else
248
 
        {
249
 
          guLogError( wxT( "Error creating the MusicDns converter" ) );
250
 
        }
251
 
        gst_object_unref( dec );
252
 
      }
253
 
      else
254
 
      {
255
 
        guLogError( wxT( "Error creating the MusicDns decoder" ) );
256
 
      }
257
 
      gst_object_unref( src );
258
 
    }
259
 
    else
260
 
    {
261
 
        guLogError( wxT( "Error creating the MusicDns source" ) );
262
 
    }
263
 
    gst_object_unref( m_Pipeline );
264
 
  }
265
 
  else
266
 
  {
267
 
        guLogError( wxT( "Error creating the MusicDns pipeline" ) );
268
 
  }
269
 
  m_MusicDns->SetStatus( Error );
270
 
}
271
 
 
272
 
// -------------------------------------------------------------------------------- //
273
 
guMusicDnsThread::~guMusicDnsThread()
274
 
{
275
 
    wxASSERT( GST_IS_OBJECT( m_Pipeline ) );
276
 
    if( GST_IS_ELEMENT( m_Pipeline ) )
277
 
    {
278
 
        gst_element_set_state( m_Pipeline, GST_STATE_NULL );
279
 
        gst_object_unref( GST_OBJECT( m_Pipeline ) );
280
 
    }
281
 
    m_MusicDns->ClearMusicDnsThread();
282
 
    //guLogMessage( wxT( "Destroyed MusicDnsThread..." ) );
283
 
}
284
 
 
285
 
// -------------------------------------------------------------------------------- //
286
 
guMusicDnsThread::ExitCode guMusicDnsThread::Entry()
287
 
{
288
 
    gst_element_set_state( m_Pipeline, GST_STATE_PLAYING );
289
 
 
290
 
    m_Running = true;
291
 
    while( !TestDestroy() && m_Running )
292
 
    {
293
 
        Sleep( 20 );
294
 
    }
295
 
    //guLogMessage( wxT( "Finished guMusicDnsThread..." ) );
296
 
    return 0;
297
 
}
298
 
 
299
 
// -------------------------------------------------------------------------------- //
300
 
void guMusicDnsThread::SetFingerprint( const char * fingerprint )
301
 
{
302
 
    m_MusicDns->SetFingerprint( fingerprint );
303
 
    Stop();
304
 
}
305
 
 
306
 
// -------------------------------------------------------------------------------- //
307
 
void guMusicDnsThread::Stop( void )
308
 
{
309
 
    m_Running = false;
310
 
}
311
 
 
312
 
// -------------------------------------------------------------------------------- //
313
 
// guMusicDns
314
 
// -------------------------------------------------------------------------------- //
315
 
guMusicDns::guMusicDns( guMusicBrainz * musicbrainz )
316
 
{
317
 
    m_MusicDnsThread = NULL;
318
 
    m_MusicBrainz = musicbrainz;
319
 
    m_Status = guMDNS_STATUS_OK;
320
 
}
321
 
 
322
 
// -------------------------------------------------------------------------------- //
323
 
guMusicDns::~guMusicDns()
324
 
{
325
 
    if( m_MusicDnsThread )
326
 
    {
327
 
        m_MusicDnsThread->Pause();
328
 
        m_MusicDnsThread->Delete();
329
 
    }
330
 
}
331
 
 
332
 
// -------------------------------------------------------------------------------- //
333
 
void guMusicDns::SetTrack( const guTrack * track )
334
 
{
335
 
    m_Track = track;
336
 
    m_Fingerprint = wxT( "" );
337
 
    m_PUID = wxT( "" );
338
 
    DoGetFingerprint();
339
 
}
340
 
 
341
 
// -------------------------------------------------------------------------------- //
342
 
wxString guMusicDns::GetXmlDoc( void )
343
 
{
344
 
    return m_XmlDoc;
345
 
}
346
 
 
347
 
// -------------------------------------------------------------------------------- //
348
 
wxString guMusicDns::GetFingerprint( void )
349
 
{
350
 
    return m_Fingerprint;
351
 
}
352
 
 
353
 
// -------------------------------------------------------------------------------- //
354
 
void guMusicDns::SetFingerprint( const wxString &fingerprint )
355
 
{
356
 
    m_Fingerprint = fingerprint;
357
 
    if( !m_Fingerprint.IsEmpty() )
358
 
        DoGetMetadata();
359
 
    else
360
 
        m_Status = guMDNS_STATUS_ERROR_NO_FINGERPRINT;
361
 
}
362
 
 
363
 
// -------------------------------------------------------------------------------- //
364
 
void guMusicDns::SetFingerprint( const char * fingerprint )
365
 
{
366
 
    SetFingerprint( wxString( fingerprint, wxConvUTF8 ) );
367
 
}
368
 
 
369
 
// -------------------------------------------------------------------------------- //
370
 
void guMusicDns::SetXmlDoc( const wxString &xmldoc )
371
 
{
372
 
    int EndPos = xmldoc.Find( wxT( "</metadata>" ) ) + 11;
373
 
    m_XmlDoc = xmldoc.Mid( 0, EndPos );
374
 
    //guLogMessage( wxT( "XmlDoc:\n%s" ), m_XmlDoc.c_str() );
375
 
    if( !m_XmlDoc.IsEmpty() )
376
 
        DoParseXmlDoc();
377
 
    else
378
 
        m_Status = guMDNS_STATUS_ERROR_NOXMLDATA;
379
 
}
380
 
 
381
 
// -------------------------------------------------------------------------------- //
382
 
wxString guMusicDns::GetPUID( void )
383
 
{
384
 
    return m_PUID;
385
 
}
386
 
 
387
 
// -------------------------------------------------------------------------------- //
388
 
void guMusicDns::SetPUID( const wxString &puid )
389
 
{
390
 
    m_PUID = puid;
391
 
    if( m_MusicDnsThread )
392
 
    {
393
 
        CancelSearch();
394
 
    }
395
 
    //guLogMessage( wxT( "Calling FoundPUID..." ) );
396
 
    m_MusicBrainz->FoundPUID( m_PUID );
397
 
}
398
 
 
399
 
// -------------------------------------------------------------------------------- //
400
 
void guMusicDns::SetPUID( const char * puid )
401
 
{
402
 
    SetPUID( wxString( puid, wxConvUTF8 ) );
403
 
}
404
 
 
405
 
// -------------------------------------------------------------------------------- //
406
 
void guMusicDns::ClearMusicDnsThread( void )
407
 
{
408
 
    m_MusicDnsThread = NULL;
409
 
}
410
 
 
411
 
// -------------------------------------------------------------------------------- //
412
 
bool guMusicDns::IsRunning( void )
413
 
{
414
 
    return m_MusicDnsThread != NULL;
415
 
}
416
 
 
417
 
// -------------------------------------------------------------------------------- //
418
 
void guMusicDns::CancelSearch( void )
419
 
{
420
 
    if( m_MusicDnsThread )
421
 
    {
422
 
        m_MusicDnsThread->Pause();
423
 
        m_MusicDnsThread->Delete();
424
 
        m_MusicDnsThread = NULL;
425
 
    }
426
 
}
427
 
 
428
 
// -------------------------------------------------------------------------------- //
429
 
bool guMusicDns::DoGetFingerprint( void )
430
 
{
431
 
    wxASSERT( m_Track );
432
 
 
433
 
    //guLogMessage( wxT( "DoGetFingerprint..." ) );
434
 
    if( m_Track )
435
 
    {
436
 
        m_MusicDnsThread = new guMusicDnsThread( this, m_Track->m_FileName.c_str() );
437
 
    }
438
 
    return m_MusicDnsThread != NULL;
439
 
}
440
 
 
441
 
// -------------------------------------------------------------------------------- //
442
 
bool guMusicDns::DoGetMetadata( void )
443
 
{
444
 
    wxString HtmlData = wxString::Format( wxT( guMUSICDNS_REQSTR_FP ),
445
 
        wxT( guMUSICDNS_CLIENT_ID ),
446
 
        wxT( ID_GUAYADEQUE_VERSION ),
447
 
        m_Fingerprint.c_str(),
448
 
        0,  // only return PUID
449
 
        m_Track->m_Bitrate,
450
 
        m_Track->m_FileName.AfterLast( wxT( '.' ) ).c_str(),
451
 
        m_Track->m_Length * 1000,
452
 
        !m_Track->m_ArtistName.IsEmpty() ? m_Track->m_ArtistName.c_str() : wxT( "unknown" ),
453
 
        !m_Track->m_SongName.IsEmpty() ? m_Track->m_SongName.c_str() : wxT( "unknown" ),
454
 
        !m_Track->m_AlbumName.IsEmpty() ? m_Track->m_AlbumName.c_str() : wxT( "unknown" ),
455
 
        m_Track->m_Number,
456
 
        !m_Track->m_GenreName.IsEmpty() ? m_Track->m_GenreName.c_str() : wxT( "unknown" ),
457
 
        wxString::Format( wxT( "%u" ), m_Track->m_Year ).c_str() );
458
 
 
459
 
 
460
 
    //guLogMessage( wxT( guMUSICDNS_BASEURL ) wxT( "%s" ), HtmlData.c_str() );
461
 
    wxCurlHTTP  http;
462
 
    http.AddHeader( wxT( "User-Agent: " ) guDEFAULT_BROWSER_USER_AGENT );
463
 
    http.AddHeader( wxT( "Accept: text/html" ) );
464
 
    http.AddHeader( wxT( "Accept-Charset: utf-8" ) );
465
 
    http.SetOpt( CURLOPT_FOLLOWLOCATION, 1 );
466
 
    if( http.Post( wxCURL_STRING2BUF( HtmlData ), HtmlData.Length(), wxT( guMUSICDNS_BASEURL ) ) )
467
 
    {
468
 
        SetXmlDoc( http.GetResponseBody() );
469
 
        return true;
470
 
    }
471
 
    else
472
 
    {
473
 
        m_Status = guMDNS_STATUS_ERROR_HTTP;
474
 
    }
475
 
    return false;
476
 
}
477
 
 
478
 
// -------------------------------------------------------------------------------- //
479
 
bool guMusicDns::ReadTrackInfo( wxXmlNode * XmlNode )
480
 
{
481
 
//    <?xml version="1.0" encoding="UTF-8"?>
482
 
//    <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:mip="http://musicip.com/ns/mip-1.0#">
483
 
//      <track>
484
 
//        <title>Song Title</title>
485
 
//        <artist>
486
 
//          <name>Artist Name</name>
487
 
//        </artist>
488
 
//        <puid-list>
489
 
//          <puid id="2c43ec65-b629-f449-3f5e-c0b69527d771"/>
490
 
//        </puid-list>
491
 
//      </track>
492
 
//    </metadata>
493
 
    if( XmlNode && XmlNode->GetName() == wxT( "track" ) )
494
 
    {
495
 
        XmlNode = XmlNode->GetChildren();
496
 
        while( XmlNode )
497
 
        {
498
 
            if( XmlNode->GetName() == wxT( "puid-list" ) )
499
 
            {
500
 
                XmlNode = XmlNode->GetChildren();
501
 
                continue;
502
 
            }
503
 
            else if( XmlNode->GetName() == wxT( "puid" ) )
504
 
            {
505
 
                wxString PUId;
506
 
                XmlNode->GetPropVal( wxT( "id" ), &PUId );
507
 
                SetPUID( PUId );
508
 
                return true;
509
 
            }
510
 
            XmlNode = XmlNode->GetNext();
511
 
        }
512
 
    }
513
 
    m_Status = guMDNS_STATUS_ERROR_XMLPARSE;
514
 
    return false;
515
 
}
516
 
 
517
 
// -------------------------------------------------------------------------------- //
518
 
bool guMusicDns::DoParseXmlDoc( void )
519
 
{
520
 
    wxStringInputStream ins( m_XmlDoc );
521
 
    wxXmlDocument XmlDoc( ins );
522
 
    wxXmlNode * XmlNode = XmlDoc.GetRoot();
523
 
    if( XmlNode && ( XmlNode->GetName() == wxT( "metadata" ) ) )
524
 
    {
525
 
        return ReadTrackInfo( XmlNode->GetChildren() );
526
 
    }
527
 
    else
528
 
        m_Status = guMDNS_STATUS_ERROR_XMLERROR;
529
 
    return false;
530
 
}
531
 
 
532
 
// -------------------------------------------------------------------------------- //
533
 
void guMusicDns::SetStatus( const int status )
534
 
{
535
 
    m_Status = status;
536
 
}
537
 
 
538
 
// -------------------------------------------------------------------------------- //
539
 
int guMusicDns::GetStatus( void )
540
 
{
541
 
    return m_Status;
542
 
}
543
 
 
544
 
// -------------------------------------------------------------------------------- //
545
 
bool guMusicDns::IsOk( void )
546
 
{
547
 
    return m_Status == guMDNS_STATUS_OK;
548
 
}
549
 
 
550
 
// -------------------------------------------------------------------------------- //