Changeset 195

Show
Ignore:
Timestamp:
01/16/08 13:40:24 (4 years ago)
Author:
ath
Message:

New sync API.

Location:
fm_server/trunk/src
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • fm_server/trunk/src/fm_element.c

    r144 r195  
    5050                                         GValue         *value, 
    5151                                         GParamSpec     *pspec); 
     52static void fm_element_become_sync_ref  (FmElement      *element); 
    5253 
    5354//static gpointer parent_class = NULL; 
     
    104105                            rgc_marshal_VOID__VOID, 
    105106                            0); 
     107 
     108        rgc_method_register ("become_sync_ref", 
     109                             FM_TYPE_ELEMENT, 
     110                             G_CALLBACK (fm_element_become_sync_ref), 
     111                             rgc_marshal_VOID__VOID, 
     112                             0); 
     113 
     114        rgc_method_register ("sync_ref_set_peer_master", 
     115                             FM_TYPE_ELEMENT, 
     116                             G_CALLBACK (fm_element_sync_ref_set_peer_master), 
     117                            rgc_marshal_VOID__ELEMENT, 
     118                            1, G_TYPE_STRING); 
    106119} 
    107120 
     
    140153        element->src_ports = NULL; 
    141154        element->sink_ports = NULL; 
     155        element->peer_sync_master = NULL; 
    142156         
    143157        element->active = FALSE;         
     
    145159 
    146160        element->pipeline = NULL; 
     161        element->sync_ref = NULL; 
     162        element->sync_master = FALSE; 
    147163} 
    148164 
     
    205221 
    206222 
    207 gpointer 
    208 fm_element_pipeline_get_sync_info       (FmElement      *element) 
    209 { 
    210         g_return_val_if_fail (element->pipeline, NULL); 
    211  
    212         FmPipeline *pipe = FM_PIPELINE (element->pipeline); 
    213         return pipe->sync_info; 
    214 } 
    215  
    216  
    217 gboolean 
    218 fm_element_is_sync_master               (FmElement      *element) 
    219 { 
    220         g_return_val_if_fail (element->pipeline, FALSE); 
    221  
    222         FmPipeline *pipe = FM_PIPELINE (element->pipeline); 
    223  
    224         if (pipe->sync_info->master == element) 
     223inline gboolean 
     224fm_element_is_sync_ref                  (FmElement      *element) 
     225{ 
     226        if (element->sync_ref) 
    225227                return TRUE; 
    226228        else 
    227229                return FALSE; 
     230} 
     231 
     232 
     233inline gboolean 
     234fm_element_is_sync_master               (FmElement      *element) 
     235{ 
     236        return element->sync_master; 
    228237} 
    229238 
     
    273282        FmElementClass *klass = FM_ELEMENT_GET_CLASS (element); 
    274283 
    275         g_print("fm_element_activate, %p\n", element); 
     284//      g_print("fm_element_activate, %p\n", element); 
    276285 
    277286        g_return_val_if_fail (!element->active, FALSE); 
     
    330339void 
    331340fm_element_get_buffer                   (FmElement      *element, 
    332                                          FmBuffer       *buffer) 
     341                                         FmBuffer       *buffer, 
     342                                         FmSync         *sync) 
    333343{ 
    334344        g_return_if_fail (FM_IS_ELEMENT (element)); 
    335         FmElementClass *class = FM_ELEMENT_GET_CLASS (element); 
     345        FmElementClass *klass = FM_ELEMENT_GET_CLASS (element); 
    336346         
    337347        /* FIXME: Check if the element has sinks */ 
     
    340350         
    341351        if (element->active) { 
    342                 if (class->get_buffer) 
    343                         (*class->get_buffer) (element, buffer); 
     352                if (klass->get_buffer) 
     353                        (*klass->get_buffer) (element, buffer, sync); 
    344354                else 
    345355                        g_print ("\"get_buffer\" method not defined for element \"%s\"!\n", 
     
    348358                if (element->sink_ports) { 
    349359                        FmElementSinkPort *sink_port = element->src_ports->data; 
    350                         fm_element_get_buffer(sink_port->owner, buffer); 
     360                        fm_element_get_buffer(sink_port->owner, buffer, sync); 
    351361                } else { 
    352362                        fm_buffer_fill_with_silence(buffer); 
     
    382392void 
    383393fm_element_get_buffer_from_src          (FmElement      *element, 
    384                                          FmBuffer       *buffer) 
     394                                         FmBuffer       *buffer, 
     395                                         FmSync         *sync) 
    385396{ 
    386397        g_return_if_fail (element->sink_ports); 
     
    390401 
    391402        if (peer_port) 
    392                 fm_element_get_buffer(FM_ELEMENT(peer_port->owner), buffer); 
     403                fm_element_get_buffer(FM_ELEMENT(peer_port->owner), buffer, sync); 
    393404        else 
    394405                fm_buffer_fill_with_silence(buffer); 
    395406         
    396407} 
     408 
     409 
     410static void 
     411fm_element_become_sync_ref              (FmElement      *element) 
     412{ 
     413        g_print ("fm_element_become_sync_ref on %p!\n", element); 
     414 
     415        element->sync_ref = g_new0 (FmSync, 1); 
     416} 
     417 
     418 
     419void 
     420fm_element_sync_ref_set_peer_master     (FmElement      *reference, 
     421                                         FmElement      *peer_sync_master) 
     422{ 
     423        g_return_if_fail (reference->sync_ref); 
     424        FmElementClass *klass = FM_ELEMENT_GET_CLASS (peer_sync_master); 
     425        g_return_if_fail (klass->become_sync_master); 
     426 
     427        g_print ("new sync master is %p %s\n", peer_sync_master, peer_sync_master->name); 
     428 
     429        reference->peer_sync_master = peer_sync_master; 
     430        peer_sync_master->sync_master = TRUE; 
     431        (*klass->become_sync_master) (peer_sync_master, reference->sync_ref); 
     432} 
  • fm_server/trunk/src/fm_element.h

    r144 r195  
    3535#define FM_ELEMENT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), FM_TYPE_ELEMENT, FmElementClass)) 
    3636 
    37 typedef enum _FmElementPads FmElementPads; 
    3837typedef struct _FmElement FmElement; 
    3938typedef struct _FmElementClass FmElementClass; 
    4039 
    41 enum _FmElementPads { 
    42         PAD_NONE, 
    43         PAD_SINGLE, 
    44         PAD_MULTIPLE 
    45 }; 
    4640 
    4741typedef struct _FmElementSrcPort FmElementSrcPort; 
     
    6458 
    6559 
     60typedef struct _FmSync FmSync; 
     61struct _FmSync { 
     62        gboolean        in_use; 
     63 
     64        FmElement       *master; 
     65 
     66        /* written from fm_element_become_sync_master */ 
     67        gdouble         bpm; 
     68        gint            beat_per_bar; 
     69 
     70        /* automatically generated */ 
     71        gdouble         ns_per_beat; 
     72 
     73        /* updated on update_cycle() */ 
     74        gint            bar; 
     75        gint            beat; 
     76        gfloat          beat_offset_ns; 
     77 
     78        gdouble         bpm_new; 
     79        guint           played_ns_new; 
     80}; 
     81 
    6682 
    6783 
     
    7187        gchar           *name; 
    7288         
    73         //FmElementPads src_pads; 
    74         /*GList         *src_list;*/ 
    75         GList           *src_ports; 
     89        GList           *src_ports;             // dove esce l'audio 
    7690         
    77         //FmElementPads sink_pads; 
    78         /*GList         *sink_list;*/ 
    79         GList           *sink_ports; 
     91        GList           *sink_ports;            // dove entra l'audio 
     92        FmElement       *peer_sync_master; 
    8093         
    8194        gboolean        active; 
     
    8497        // yes, I know this is an hack 
    8598        gpointer        pipeline; 
     99 
     100        FmSync          *sync_ref; 
     101        gboolean        sync_master; 
    86102}; 
    87103 
     
    95111        gboolean (*activate)            (FmElement      *element); 
    96112        gboolean (*deactivate)          (FmElement      *element); 
    97         void (*become_sync_master)      (FmElement      *element); 
     113        void (*become_sync_ref)         (FmElement      *element, 
     114                                         FmSync         *sync); 
     115        void (*become_sync_master)      (FmElement      *element, 
     116                                         FmSync         *sync); 
    98117        void (*get_buffer)              (FmElement      *element, 
    99                                          FmBuffer       *buffer); 
     118                                         FmBuffer       *buffer, 
     119                                         FmSync         *sync); 
    100120}; 
    101121 
     
    114134fm_element_get_name                     (FmElement      *element); 
    115135 
    116 gpointer 
    117 fm_element_pipeline_get_sync_info       (FmElement      *element); 
     136inline gboolean 
     137fm_element_is_sync_ref                  (FmElement      *element); 
    118138 
    119 gboolean 
     139inline gboolean 
    120140fm_element_is_sync_master               (FmElement      *element); 
    121141 
     
    138158void 
    139159fm_element_get_buffer                   (FmElement      *element, 
    140                                          FmBuffer       *buffer); 
     160                                         FmBuffer       *buffer, 
     161                                         FmSync         *sync); 
    141162 
    142163void 
     
    148169void 
    149170fm_element_get_buffer_from_src          (FmElement      *element, 
    150                                          FmBuffer       *buffer); 
     171                                         FmBuffer       *buffer, 
     172                                         FmSync         *sync); 
     173 
     174void 
     175fm_element_sync_ref_set_peer_master     (FmElement      *reference, 
     176                                         FmElement      *peer_sync_master); 
  • fm_server/trunk/src/fm_pipeline.c

    r133 r195  
    2323 * 
    2424 */ 
     25 
    2526 
    2627#include <glib.h> 
     
    8990                             1, G_TYPE_STRING); 
    9091 
    91         rgc_method_register ("set_sync_master", 
     92/*      rgc_method_register ("set_sync_master", 
    9293                             FM_TYPE_PIPELINE, 
    9394                             G_CALLBACK (fm_pipeline_set_beat_master), 
    9495                             rgc_marshal_VOID__ELEMENT, 
    95                              1, G_TYPE_STRING); 
     96                             1, G_TYPE_STRING);*/ 
    9697 
    9798        rgc_method_register ("add_element", 
     
    191192 
    192193 
    193 void 
     194/*void 
    194195fm_pipeline_set_beat_master             (FmPipeline     *pipeline, 
    195196                                         FmElement      *element) 
     
    205206        if (klass->become_sync_master) 
    206207                (*klass->become_sync_master) (element); 
    207 } 
     208}*/ 
    208209 
    209210 
  • fm_server/trunk/src/fm_pipeline.h

    r126 r195  
    7676                                         FmElement      *element); 
    7777 
    78 void 
     78/*void 
    7979fm_pipeline_set_beat_master             (FmPipeline     *pipeline, 
    80                                          FmElement      *element); 
     80                                         FmElement      *element);*/ 
    8181 
    8282void 
  • fm_server/trunk/src/fm_sync.c

    r143 r195  
    4646        } 
    4747 
    48         guint sample_rate = /* fm_pipeline_get_sample_rate() */ 44100; 
    49         sync->ns_per_sample = (1.0 / sample_rate) * NS_PER_SEC; 
     48//      guint sample_rate = /* fm_pipeline_get_sample_rate() */ 44100; 
     49//      sync->ns_per_sample = (1.0 / sample_rate) * NS_PER_SEC; 
    5050        sync->ns_per_beat = NS_PER_SEC / (sync->bpm / 60.0); 
    5151 
    5252//      g_print ("ns_per_sample %lf ns_per_beat %lf\n", sync->ns_per_sample, sync->ns_per_beat); 
    5353 
    54         sync->beat_offset_ns += sync->played_samples_new * sync->ns_per_sample; 
     54        sync->beat_offset_ns += sync->played_ns_new; 
    5555 
    5656        //G_BREAKPOINT(); 
     
    6969 
    7070void 
    71 fm_sync_master_played_samples           (FmSync         *sync, 
    72                                          guint          samples) 
     71fm_sync_master_played_ns                (FmSync         *sync, 
     72                                         guint          ns) 
    7373{ 
    74         sync->played_samples_new = samples; 
     74        sync->played_ns_new = ns; 
    7575} 
    7676 
     
    8383} 
    8484 
     85void 
     86fm_sync_set                             (FmSync         *sync, 
     87                                         guint64        offset, 
     88                                         guint64        timestamp) 
     89{ 
     90        guint64 realstamp = timestamp - offset; 
     91        guint beats = realstamp / sync->ns_per_beat; 
     92        sync->bar = beats / sync->beat_per_bar; 
     93        sync->beat = beats - (sync->bar * sync->beat_per_bar); 
     94        sync->beat_offset_ns = realstamp - (beats * sync->ns_per_beat); 
     95 
     96} 
    8597 
    8698gdouble 
     
    88100{ 
    89101        return (sync->ns_per_beat - sync->beat_offset_ns); 
    90 } 
    91  
    92  
    93 gint 
    94 fm_sync_samples_to_next_beat            (FmSync         *sync) 
    95 { 
    96         return (fm_sync_ns_to_next_beat (sync) / sync->ns_per_sample); 
    97102} 
    98103 
     
    108113        return next_beat; 
    109114} 
     115 
     116void 
     117fm_sync_show_pos                        (FmSync         *sync) 
     118{ 
     119        g_print ("bpm: %lf pos: bar %d beat %d beat_offset_ns %f\n", sync->bpm, sync->bar, sync->beat, sync->beat_offset_ns); 
     120} 
  • fm_server/trunk/src/fm_sync.h

    r143 r195  
    2424typedef struct _FmBeatSection FmBeatSection; 
    2525typedef struct _FmBeatInfo FmBeatInfo; 
    26 typedef struct _FmSync FmSync; 
    2726 
    2827 
     
    3837}; 
    3938 
     39/* 
     40struct _FmBufferRequest { 
     41        gboolean        cont; 
     42        guint64         pos; 
     43        guint           req_samples; 
     44}; 
    4045 
    41 struct _FmSync { 
    42         FmElement       *master; 
     46enum FmBufferReturn { 
     47        FM_BUFFER_RETURN_OK, 
     48        FM_BUFFER_RETURN_DISCONT 
    4349 
    44         /* written from fm_element_beacome_sync_master */ 
    45         gdouble         bpm; 
    46         gint            beat_per_bar; 
    47  
    48         /* automatically generated */ 
    49         gdouble         ns_per_sample; 
    50         gdouble         ns_per_beat; 
    51  
    52         /* automatically updated at the beginning of each cycle */ 
    53         gint            bar; 
    54         gint            beat; 
    55         gfloat          beat_offset_ns; 
    56  
    57         /* can be updated with the functions below */ 
    58         gdouble         bpm_new; 
    59         guint           played_samples_new; 
    60 }; 
     50};*/ 
    6151 
    6252 
     
    6454fm_sync_new                             (void); 
    6555 
    66 /* Every output element must call this after get_buffer */ 
     56/* The sync reference has to call this after calling fm_get_buffer() on its peer_sync_master port */ 
    6757void 
    6858fm_sync_update_cycle                    (FmSync         *sync); 
     
    7060/* Callable from get_buffer, takes effect from next cycle */ 
    7161void 
    72 fm_sync_master_played_samples           (FmSync         *sync, 
     62fm_sync_master_played_ns                (FmSync         *sync, 
    7363                                         guint          samples); 
    7464 
     
    7868                                         gdouble        bpm); 
    7969 
     70void 
     71fm_sync_set                             (FmSync         *sync, 
     72                                         guint64        offset, 
     73                                         guint64        timestamp); 
     74 
    8075/* Callable from get_buffer */ 
    8176gdouble 
     
    8378 
    8479gint 
    85 fm_sync_samples_to_next_beat            (FmSync         *sync); 
     80fm_sync_next_beat_is                    (FmSync         *sync); 
    8681 
    87 gint 
    88 fm_sync_next_beat_is                    (FmSync         *sync); 
     82void 
     83fm_sync_show_pos                        (FmSync         *sync);