Main Page   Data Structures   File List   Data Fields   Globals  

libdaisy.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by André Lindhjem <belgarat@sdf.lonestar.org>,     *
00003  *                         Kjetil Holien <kjetil.holien@gmail.com>,        *
00004  *                         Terje Risa <terje.risa@gmail.com> &             *
00005  *                         Øyvind Nerbråten <oyvind@nerbraten.com>         *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************
00022  *
00023  * \file libdaisy.c
00024  * \author André Lindhjem, Kjetil Holien, Terje Risa & Øyvind Nerbråten
00025  * \date 21.03.2006
00026  * 
00027  * Libdaisy is a toolkit for parsing and playing Daisy Digital Talking Books (DTB).
00028  */
00029  
00030  
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include <assert.h>
00036 
00037 #include "libdaisy.h"
00038 #include "control.h"
00039 #include "common.h"
00040 #include "snprintf/snprintf.h"
00041 #include "audio.h"
00042 #include "report.h"
00043 
00044 #define DAISYPLAYER_MAGIC_NUMBER 0xC729A4BF
00045 
00046 
00047 
00052 typedef struct {
00053     void        *data;  /* user-defined pointer to data. this will be availible in all callback functions */
00054     void        (*cb_daisy_audio_done)  (void *);   /* (data, progress_ms_t);   called when libdaisy are done playing an audio segment */
00055     void        (*cb_daisy_audio_next)  (void *, unsigned long int);    /* (data, void) called when daisy are playing audio */
00056     void        (*cb_daisy_text)        (void *, void *);   /* (data, passage); called when daisy have parsed a text-passage */
00057     void        (*cb_daisy_id)          (void *, void *);   /* (data, id);  called when daisy have parsed an id */
00058     void        (*cb_daisy_error)       (void *, enum daisy_status, const char *daisy_status_msg);
00059     void        (*cb_daisy_progress)    (void *, long int); /* (data, progress_ms) */
00060     
00061     void *audio_data;   /* data related to audio decoding and playback */
00062     struct DaisyData *daisy_book_data;
00063     unsigned int magic; /* magic number that verifies if the struct is valid or not */
00064     
00065     pthread_mutex_t daisy_mutex;    /* mutex used in libdaisy.c */
00066 
00067 } struct_daisyplayer_t;
00068 
00069 
00070 
00071 /* ************************************************ *
00072  *          Static function declarations            *
00073  * ************************************************ */
00074 
00082 static void local_cb_daisy_audio_done (daisyplayer_t daisy);
00083 
00097 static audio_data_t start_audio (daisyplayer_t  daisy,
00098                   void (*done) (daisyplayer_t),
00099                   void (*error) (void *data, enum daisy_status, const char *),
00100                   void (*progress) (void *data, long int progress_ms));
00101 
00107 static void stop_audio (daisyplayer_t   daisy, audio_data_t data);
00108 
00109 
00110 
00111 /* ************************************************ *
00112  *          Static function definitions             *
00113  * ************************************************ */
00114 
00122 static void local_cb_daisy_audio_done (daisyplayer_t daisy)
00123 {
00124     int result;
00125     struct_daisyplayer_t *_daisy = daisy;
00126     
00127     _daisy->cb_daisy_audio_done (_daisy->data); /* call the done playing a passage callback function */
00128 
00129     result = daisy_seek (_daisy, DAISY_SEEK_NEXT_PASSAGE);  /* seek to the next passage and continue playing */
00130 
00131     if (result != 1 )
00132     {
00133         if (result == 0)
00134         {
00135             _daisy->cb_daisy_error (_daisy->data, DAISY_END_OF_BOOK, NULL);
00136         }   
00137         else                
00138         {
00139             _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_SEEK_FAILED, NULL);
00140         }
00141     }
00142 }
00143 
00157 static audio_data_t start_audio (daisyplayer_t  daisy,
00158                   void          (*done)     (daisyplayer_t d),
00159                   void          (*error)    (void *data, enum daisy_status, const char *daisy_error_msg),
00160                   void          (*progress) (void *data, long int progress_ms))
00161 {
00162     audio_data_t ret;
00163     struct_daisyplayer_t *_daisy = daisy;
00164     
00165     ret = audio_initiate (_daisy, done, error, progress);
00166 
00167     if (DEBUG_DAISYPLAYER) report ("control.c: in start_audio", REP_DEBUG);
00168 
00169     if (pthread_create (&_daisy->daisy_book_data->thread_audio, NULL, &audio_thread, ret))
00170     {
00171         report ("Error creating audio thread", REP_CRITICAL);
00172         return NULL; /* fail */
00173     }
00174     else
00175     {
00176         if (DEBUG_DAISYPLAYER) report ("control.c: audio_thread started", REP_DEBUG);
00177     }
00178 
00179     return ret; /* succeed */
00180 }
00181 
00187 static void stop_audio (daisyplayer_t daisy, audio_data_t data)
00188 {
00189     struct_daisyplayer_t *_daisy = daisy;
00190     
00191     audio_terminate(data);      /* tell audiomodule to terminate and clean up   */
00192     pthread_cancel (_daisy->daisy_book_data->thread_audio);
00193 }
00194 
00195 
00196 
00197 /* ************************************************** *
00198  *          Global function definitions               *
00199  * ************************************************** */
00200  
00216 daisyplayer_t daisy_init (void *data,
00217                           void (*l_cb_daisy_audio_done) (void *),                   /* (data, progress_ms_t ), */
00218                           void (*l_cb_daisy_audio_next) (void *, unsigned long int),/* (data, void), */
00219                           void (*l_cb_daisy_text)       (void *, void *),           /* (data, passage_t ), */
00220                           void (*l_cb_daisy_id)         (void *, void *),           /* (data, id_t ) */
00221                           void (*l_cb_daisy_error)      (void *, enum daisy_status, const char *),
00222                           void (*l_cb_daisy_progress)   (void *, long int))         /* (data, progress_ms) */
00223                           
00224 {
00225     struct_daisyplayer_t *daisy = malloc (sizeof(struct_daisyplayer_t));    /* allocates space for struct daisyplayer */
00226 
00227     daisy->magic = DAISYPLAYER_MAGIC_NUMBER;    /* set magic number */
00228     
00229     if (pthread_mutex_init(&daisy->daisy_mutex, NULL) != 0) {
00230         l_cb_daisy_error (daisy, DAISY_ERROR_MISC_INIT_MUTEX, NULL);
00231         report ("Could not initialize daisy->daisy_mutex", REP_ERROR);
00232         return NULL; /* fail */
00233     }   
00234     /* store away users data pointer */
00235     daisy->data = data;
00236 
00237     /* initiates the callback functions */
00238     daisy->cb_daisy_audio_done  = l_cb_daisy_audio_done;
00239     daisy->cb_daisy_audio_next  = l_cb_daisy_audio_next;
00240     daisy->cb_daisy_text        = l_cb_daisy_text;
00241     daisy->cb_daisy_id          = l_cb_daisy_id;
00242     daisy->cb_daisy_error       = l_cb_daisy_error;
00243     daisy->cb_daisy_progress    = l_cb_daisy_progress;
00244     
00245     /* initiates the parser and data structure */
00246     daisy->daisy_book_data = parseInit ();
00247 
00248     /* initiate the audio thread */
00249     daisy->audio_data = start_audio (daisy, local_cb_daisy_audio_done, daisy->cb_daisy_error, daisy->cb_daisy_progress);
00250     assert (daisy->magic == DAISYPLAYER_MAGIC_NUMBER);
00251     return daisy;
00252 }
00253 
00259 void daisy_term (daisyplayer_t daisy)
00260 {   
00261     struct_daisyplayer_t *_daisy = daisy;
00262 
00263     if (DEBUG_DAISYPLAYER) report ("daisy_term\n", REP_DEBUG);
00264     
00265     parseTerminate (_daisy->daisy_book_data);   /* deallocates the data structure and cleans up after the parser */
00266 
00267     stop_audio(_daisy, _daisy->audio_data);
00268     
00269     _daisy->magic = 0x00000000;
00270     free (_daisy);      /* frees the daisy struct */
00271 }
00272 
00279 int daisy_load (daisyplayer_t daisy, char *path)
00280 {
00281     int result;
00282     struct_daisyplayer_t *_daisy = daisy;
00283     
00284     if (DEBUG_DAISYPLAYER) report ("daisy_load\n", REP_DEBUG);
00285     
00286     stop_audio(_daisy, _daisy->audio_data); _daisy->audio_data = NULL;
00287     _daisy->audio_data = start_audio(_daisy, local_cb_daisy_audio_done, _daisy->cb_daisy_error, _daisy->cb_daisy_progress);
00288     
00289     result = parse (_daisy->daisy_book_data, path);
00290     if (result != 1)
00291         return result;
00292     result = seek (_daisy->daisy_book_data, DAISY_SEEK_NEXT_PASSAGE);
00293     return result;
00294 }
00295 
00301 int daisy_play (daisyplayer_t daisy)
00302 {
00303     struct_daisyplayer_t *_daisy = daisy;
00304     unsigned long int duration_ms;
00305     char audiopath[STRLEN];
00306 
00307     if (DEBUG_DAISYPLAYER) report ("daisy_play\n", REP_DEBUG);
00308     
00309     /* check if a daisy dtb is loaded */
00310     if (_daisy->daisy_book_data->smilHead->next == _daisy->daisy_book_data->smilTail)
00311     {
00312         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00313         return -1;  
00314     }
00315 
00316     /* starting audio */
00317     if (_daisy->daisy_book_data->nodePos->audiofilename != NULL)
00318     {
00319         snprintf (audiopath, sizeof (audiopath), "%s%s", _daisy->daisy_book_data->path, _daisy->daisy_book_data->nodePos->audiofilename);
00320         duration_ms = audio_play (_daisy->audio_data, audiopath, _daisy->daisy_book_data->nodePos->audioStartPos, _daisy->daisy_book_data->nodePos->audioStopPos);
00321         if ((int) duration_ms == -1)
00322             return -1;  /* error! */
00323         _daisy->cb_daisy_audio_next (_daisy->data, duration_ms);    /* we start playing a passage */
00324     }
00325     else
00326     {
00327         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_AUDIO_IN_SEGMENT, NULL);
00328     }
00329 
00330     /* reporting id and text */
00331     if (_daisy->daisy_book_data->nodePos->textPassage != NULL && _daisy->daisy_book_data->nodePos->fragmentIdentifier != NULL)
00332     {
00333         _daisy->cb_daisy_id (_daisy->data, (void *) _daisy->daisy_book_data->nodePos->fragmentIdentifier);  /* output id */
00334         _daisy->cb_daisy_text (_daisy->data, (void *) _daisy->daisy_book_data->nodePos->textPassage);   /* output text */
00335     }
00336     else
00337     {
00338         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_TEXT_IN_SEGMENT, NULL);   
00339     }
00340     
00341     return 1;   /* success */
00342 }
00343 
00351 int daisy_seek (daisyplayer_t daisy, int seek_option)
00352 {
00353     struct_daisyplayer_t *_daisy = daisy;
00354     audio_state_t aState;
00355     
00356     if (DEBUG_DAISYPLAYER) report ("daisy_seek\n", REP_DEBUG);
00357 
00358     /*pthread_mutex_lock (&_daisy->daisy_mutex);*/ /* locking mutex */
00359     if (pthread_mutex_trylock (&_daisy->daisy_mutex) != 0) /* trying to locking mutex, return -1 on failed */
00360     {
00361         return -1;
00362     }
00363     
00364     if (DEBUG_THREADS) report ("daisy_seek has daisy_mutex", REP_DEBUG);
00365 
00366     /* check if a daisy dtb is loaded */
00367     if (_daisy->daisy_book_data->smilHead->next == _daisy->daisy_book_data->smilTail)
00368     {
00369         pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00370         if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00371         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00372         return -1;
00373     }
00374 
00375     /* check the state of the audio engine */
00376     aState = audio_get_state (_daisy->audio_data);
00377 
00378     if (aState != AUDIO_STATE_STOP) /* don't stop if state already is stopped */
00379     {
00380         if (audio_stop (_daisy->audio_data) != 1)   /* try stopping playback */
00381         {
00382             pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00383             if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00384             return -1;
00385         }
00386     }
00387 
00388     if (audio_get_state (_daisy->audio_data) == AUDIO_STATE_STOP)
00389     {
00390         int ret = seek (_daisy->daisy_book_data, seek_option);
00391 
00392         if (ret != 1)   /* seek if stop was successful */
00393         {
00394             pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00395             
00396             if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00397 
00398             if (ret == 0)
00399             {
00400                 return 0;
00401             }
00402             else
00403             {
00404                 return -1;
00405             }
00406         }
00407     } else {
00408         pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00409         if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00410         return -1;
00411     }
00412 
00413     if (daisy_play(_daisy) != 1)    /* try starting playback */
00414     {
00415         pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00416         if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00417         return -1;
00418     }
00419 
00420     pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00421 
00422     if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00423 
00424     return 1;
00425 }
00426 
00435 daisy_position *daisy_get_position (daisyplayer_t daisy)
00436 {
00437     struct_daisyplayer_t *_daisy = daisy;
00438     int smilp = 0, nodep = 0;
00439     daisy_position *position = NULL;
00440     
00441     if (DEBUG_DAISYPLAYER) report ("daisy_get_bookmark\n", REP_DEBUG);
00442     
00443     /* check if a daisy dtb is loaded */
00444     if (_daisy->daisy_book_data->smilHead->next == _daisy->daisy_book_data->smilTail)
00445     {
00446         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00447         return NULL;    
00448     }
00449     
00450     smilp = getSmilPos(_daisy->daisy_book_data);
00451     nodep = getNodePos(_daisy->daisy_book_data);
00452     
00453     if (smilp != -1 && nodep != -1)
00454     {
00455         /* store positions if we successful retrieved them both */
00456         position = (daisy_position *) malloc (sizeof (daisy_position));
00457         position->smilpos = smilp;
00458         position->nodepos = nodep;
00459     } else
00460         return NULL;
00461 
00462     return position;
00463 }
00464 
00473 int daisy_goto_position (daisyplayer_t daisy, daisy_position *position)
00474 {   
00475     struct_daisyplayer_t *_daisy = daisy;
00476     audio_state_t aState;
00477 
00478     if (DEBUG_DAISYPLAYER) report ("daisy_goto_bookmark\n", REP_DEBUG);
00479     
00480     pthread_mutex_lock (&_daisy->daisy_mutex); /* locking mutex */
00481     if (DEBUG_THREADS) report ("daisy_seek has daisy_mutex", REP_DEBUG);
00482     
00483     /* check if a daisy dtb is loaded */
00484     if (_daisy->daisy_book_data->smilHead->next == _daisy->daisy_book_data->smilTail)
00485     {
00486         pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00487         if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00488         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00489         return -1;
00490     }
00491     
00492     /* check the state of the audio engine */
00493     aState = audio_get_state (_daisy->audio_data);
00494     
00495     if (aState != AUDIO_STATE_STOP) /* don't stop if state already is stopped */
00496     {
00497         if (audio_stop (_daisy->audio_data) != 1)   /* try stopping playback */
00498         {
00499             pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00500             if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00501             return -1;
00502         }
00503     }
00504     if (audio_get_state (_daisy->audio_data) == AUDIO_STATE_STOP)
00505     {
00506         if (gotoSmilPosition (_daisy->daisy_book_data, position->smilpos) != 1 || gotoNodePosition (_daisy->daisy_book_data, position->nodepos) != 1)   /* jump if stop was successful */
00507         {
00508             pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00509             if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00510             return -1;
00511         }
00512     } else {
00513         pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00514         if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00515         return -1;
00516     }
00517 
00518     if (daisy_play(_daisy) != 1)    /* try starting playback */
00519     {
00520         pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00521         if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00522         return -1;
00523     }
00524 
00525     pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00526     if (DEBUG_THREADS) report ("daisy_seek released_mutex", REP_DEBUG);
00527     return 1;   
00528 }
00529 
00535 int daisy_stop (daisyplayer_t daisy)
00536 {
00537     int ret = 0;
00538     struct_daisyplayer_t  *_daisy = daisy;
00539     if (pthread_mutex_trylock (&_daisy->daisy_mutex) != 0) /* trying to locking mutex, return -1 on failed */
00540         return -1;
00541     if (DEBUG_DAISYPLAYER) report ("daisy_stop\n", REP_DEBUG);
00542     ret =  audio_stop (_daisy->audio_data);
00543     pthread_mutex_unlock (&_daisy->daisy_mutex); /* unlocking mutex */
00544     return ret;
00545 }
00546 
00552 int daisy_pause (daisyplayer_t daisy)
00553 {
00554     struct_daisyplayer_t *_daisy = daisy;
00555     if (DEBUG_DAISYPLAYER) report ("daisy_pause\n", REP_DEBUG);
00556     return audio_pause (_daisy->audio_data);
00557 }
00558 
00566 char* daisy_get_info (daisyplayer_t daisy, int value)
00567 {
00568     char* returnvalue = NULL;
00569     
00570     struct_daisyplayer_t *_daisy = daisy;
00571     
00572     /* check if a daisy dtb is loaded */
00573     if (_daisy->daisy_book_data->smilHead->next == _daisy->daisy_book_data->smilTail)
00574     {
00575         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00576         return NULL;
00577     }
00578     
00579     /* get title */
00580     if(value == DAISY_BOOKINFO_TITLETEXT)
00581     {
00582         /* checks if the value isn't NULL */
00583         if(_daisy->daisy_book_data->bookInfo->titleText != NULL)
00584         {   
00585             /* malloc thenew string and copy the book info in this string */
00586             returnvalue = (char *) malloc (strlen ((char *)_daisy->daisy_book_data->bookInfo->titleText)+1);
00587             strcpy (returnvalue, _daisy->daisy_book_data->bookInfo->titleText);
00588         }
00589     }
00590     /* get title image */
00591     else if(value == DAISY_BOOKINFO_TITLEIMAGE)
00592     {
00593         if(_daisy->daisy_book_data->bookInfo->titleImage != NULL)
00594         {
00595             returnvalue = (char *) malloc (strlen ((char *)_daisy->daisy_book_data->bookInfo->titleImage)+1);
00596             strcpy (returnvalue, _daisy->daisy_book_data->bookInfo->titleImage);
00597         }       
00598     }
00599     /* get total time */
00600     else if(value == DAISY_BOOKINFO_TOTALTIME)
00601     {
00602         if(_daisy->daisy_book_data->bookInfo->totalTime != NULL)
00603         {
00604             returnvalue = (char *) malloc (strlen ((char *)_daisy->daisy_book_data->bookInfo->totalTime)+1);
00605             strcpy (returnvalue, _daisy->daisy_book_data->bookInfo->totalTime);
00606         }       
00607     }
00608     /* unvalid value */
00609     else return NULL;
00610     return returnvalue;
00611 }
00612 
00618 int daisy_get_chapter_count (daisyplayer_t daisy)
00619 {
00620     int count = 0;
00621     struct SmilNode *tmpSmil = NULL;
00622     struct_daisyplayer_t *_daisy = daisy;
00623     
00624     tmpSmil = _daisy->daisy_book_data->smilHead;
00625     /* check if a daisy DTB is loaded */
00626     if (tmpSmil->next == _daisy->daisy_book_data->smilTail)
00627     {
00628         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00629         return -1;
00630     }
00631     /* move to the first node */
00632     tmpSmil = tmpSmil->next; 
00633     /* count the smil nodes */
00634     while (tmpSmil != _daisy->daisy_book_data->smilTail)
00635     {
00636         count++;
00637         tmpSmil = tmpSmil->next;
00638     }
00639     /* return the counted value */
00640     return count;
00641 }
00642 
00653 char *daisy_get_chapter_info (daisyplayer_t daisy, int num, int option)
00654 {
00655     int i = 0;
00656     char *value = NULL;
00657     struct SmilNode *tmpSmil = NULL;
00658     struct_daisyplayer_t *_daisy = daisy;
00659     
00660     /* check the parameter value num */
00661     if (num < 1)
00662         return NULL;
00663     tmpSmil = _daisy->daisy_book_data->smilHead;
00664     /* check if a daisy DTB is loaded */
00665     if (tmpSmil->next == _daisy->daisy_book_data->smilTail)
00666     {
00667         _daisy->cb_daisy_error (_daisy->data, DAISY_ERROR_PLAYBACK_NO_DTB_LOADED, NULL);
00668         return NULL;
00669     }
00670     /* move to the gived smil number */
00671     for (i = 0; i<num && tmpSmil != _daisy->daisy_book_data->smilTail; i++)
00672     {
00673         tmpSmil = tmpSmil->next;    
00674     }
00675     if (tmpSmil == _daisy->daisy_book_data->smilTail)
00676         return NULL;
00677     /* return the value */
00678     switch (option)
00679     {
00680         case DAISY_CHAPTER_TITLE:
00681             value = tmpSmil->header;
00682             return value;
00683             break;
00684         
00685         case DAISY_CHAPTER_WEIGHT: /* not implemented yet */
00686             return NULL;
00687             break;
00688             
00689         default:
00690             return NULL;    
00691     }
00692 }

Generated on Tue Sep 5 12:14:07 2006 for libdaisy by doxygen1.2.15