File indexing completed on 2024-05-19 04:56:31
0001 /** 0002 * \file oggfile.hpp 0003 * Handling of Ogg files. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 26 Sep 2005 0008 * 0009 * Copyright (C) 2005-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #pragma once 0028 0029 #include <QList> 0030 #include "oggflacconfig.h" 0031 #include "taggedfile.h" 0032 0033 0034 /** List box item containing OGG file */ 0035 class OggFile : public TaggedFile { 0036 public: 0037 /** 0038 * Constructor. 0039 * 0040 * @param idx index in tagged file system model 0041 */ 0042 explicit OggFile(const QPersistentModelIndex& idx); 0043 0044 /** 0045 * Destructor. 0046 */ 0047 ~OggFile() override = default; 0048 0049 /** 0050 * Get key of tagged file format. 0051 * @return "OggMetadata". 0052 */ 0053 QString taggedFileKey() const override; 0054 0055 /** 0056 * Get features supported. 0057 * @return bit mask with Feature flags set. 0058 */ 0059 int taggedFileFeatures() const override; 0060 0061 /** 0062 * Read tags from file. 0063 * 0064 * @param force true to force reading even if tags were already read. 0065 */ 0066 void readTags(bool force) override; 0067 0068 /** 0069 * Write tags to file and rename it if necessary. 0070 * 0071 * @param force true to force writing even if file was not changed. 0072 * @param renamed will be set to true if the file was renamed, 0073 * i.e. the file name is no longer valid, else *renamed 0074 * is left unchanged 0075 * @param preserve true to preserve file time stamps 0076 * 0077 * @return true if ok, false if the file could not be written or renamed. 0078 */ 0079 bool writeTags(bool force, bool* renamed, bool preserve) override; 0080 0081 /** 0082 * Free resources allocated when calling readTags(). 0083 * 0084 * @param force true to force clearing even if the tags are modified 0085 */ 0086 void clearTags(bool force) override; 0087 0088 /** 0089 * Remove frames. 0090 * 0091 * @param tagNr tag number 0092 * @param flt filter specifying which frames to remove 0093 */ 0094 void deleteFrames(Frame::TagNumber tagNr, const FrameFilter& flt) override; 0095 0096 0097 /** 0098 * Check if tag information has already been read. 0099 * 0100 * @return true if information is available, 0101 * false if the tags have not been read yet, in which case 0102 * hasTag() does not return meaningful information. 0103 */ 0104 bool isTagInformationRead() const override; 0105 0106 /** 0107 * Check if file has a tag. 0108 * 0109 * @param tagNr tag number 0110 * @return true if a tag is available. 0111 * @see isTagInformationRead() 0112 */ 0113 bool hasTag(Frame::TagNumber tagNr) const override; 0114 0115 /** 0116 * Get technical detail information. 0117 * 0118 * @param info the detail information is returned here 0119 */ 0120 void getDetailInfo(DetailInfo& info) const override; 0121 0122 /** 0123 * Get duration of file. 0124 * 0125 * @return duration in seconds, 0126 * 0 if unknown. 0127 */ 0128 unsigned getDuration() const override; 0129 0130 /** 0131 * Get file extension including the dot. 0132 * 0133 * @return file extension ".ogg". 0134 */ 0135 QString getFileExtension() const override; 0136 0137 /** 0138 * Get the format of tag. 0139 * 0140 * @param tagNr tag number 0141 * @return "Vorbis". 0142 */ 0143 QString getTagFormat(Frame::TagNumber tagNr) const override; 0144 0145 /** 0146 * Get a specific frame from the tags. 0147 * 0148 * @param tagNr tag number 0149 * @param type frame type 0150 * @param frame the frame is returned here 0151 * 0152 * @return true if ok. 0153 */ 0154 bool getFrame(Frame::TagNumber tagNr, Frame::Type type, Frame& frame) const override; 0155 0156 /** 0157 * Set a frame in the tags. 0158 * 0159 * @param tagNr tag number 0160 * @param frame frame to set 0161 * 0162 * @return true if ok. 0163 */ 0164 bool setFrame(Frame::TagNumber tagNr, const Frame& frame) override; 0165 0166 /** 0167 * Add a frame in the tags. 0168 * 0169 * @param tagNr tag number 0170 * @param frame frame to add 0171 * 0172 * @return true if ok. 0173 */ 0174 bool addFrame(Frame::TagNumber tagNr, Frame& frame) override; 0175 0176 /** 0177 * Delete a frame in the tags. 0178 * 0179 * @param tagNr tag number 0180 * @param frame frame to delete. 0181 * 0182 * @return true if ok. 0183 */ 0184 bool deleteFrame(Frame::TagNumber tagNr, const Frame& frame) override; 0185 0186 /** 0187 * Get all frames in tag. 0188 * 0189 * @param tagNr tag number 0190 * @param frames frame collection to set. 0191 */ 0192 void getAllFrames(Frame::TagNumber tagNr, FrameCollection& frames) override; 0193 0194 /** 0195 * Get a list of frame IDs which can be added. 0196 * @param tagNr tag number 0197 * @return list with frame IDs. 0198 */ 0199 QStringList getFrameIds(Frame::TagNumber tagNr) const override; 0200 0201 protected: 0202 /** Vorbis comment field. */ 0203 class CommentField { 0204 public: 0205 /** Constructor. */ 0206 CommentField(const QString& name = QString(), 0207 const QString& value = QString()) 0208 : m_name(name), m_value(value) {} 0209 /** 0210 * Get name. 0211 * @return name. 0212 */ 0213 QString getName() const { return m_name; } 0214 /** 0215 * Get value. 0216 * @return value. 0217 */ 0218 QString getValue() const { return m_value; } 0219 /** 0220 * Set value. 0221 * @param value value 0222 */ 0223 void setValue(const QString& value) { m_value = value; } 0224 0225 private: 0226 QString m_name; 0227 QString m_value; 0228 }; 0229 0230 /** Vorbis comment list. */ 0231 class CommentList : public QList<CommentField> { 0232 public: 0233 /** Constructor. */ 0234 CommentList() {} 0235 /** Destructor. */ 0236 ~CommentList() {} 0237 /** 0238 * Get value. 0239 * @param name name 0240 * @return value, "" if not found. 0241 */ 0242 QString getValue(const QString& name) const; 0243 /** 0244 * Set value. 0245 * @param name name 0246 * @param value value 0247 * @return true if value was changed. 0248 */ 0249 bool setValue(const QString& name, const QString& value); 0250 }; 0251 0252 /** 0253 * Get text field. 0254 * 0255 * @param name name 0256 * @return value, "" if not found, 0257 * QString::null if the tags have not been read yet. 0258 */ 0259 QString getTextField(const QString& name) const; 0260 0261 /** 0262 * Set text field. 0263 * If value is null or the tags have not been read yet, nothing is changed. 0264 * If value is different from the current value, changed is set. 0265 * 0266 * @param name name 0267 * @param value value, "" to remove, QString::null to do nothing 0268 * @param type frame type 0269 */ 0270 void setTextField(const QString& name, const QString& value, 0271 const Frame::ExtendedType& type); 0272 0273 protected: 0274 /** true if file has been read. */ 0275 bool m_fileRead; 0276 /** Comments of this file. */ 0277 CommentList m_comments; 0278 0279 /** Information about Ogg/Vorbis file. */ 0280 struct FileInfo { 0281 /** Constructor. */ 0282 FileInfo() : version(0), channels(0), 0283 sampleRate(0), bitrate(0), duration(0), valid(false) {} 0284 0285 int version; /**< vorbis encoder version */ 0286 int channels; /**< number of channels */ 0287 long sampleRate; /**< sample rate in Hz */ 0288 long bitrate; /**< bitrate in bits/s */ 0289 long duration; /**< duration in seconds */ 0290 bool valid; /**< true if read() was successful */ 0291 }; 0292 0293 /** Info about file. */ 0294 FileInfo m_fileInfo; 0295 0296 private: 0297 OggFile(const OggFile&); 0298 OggFile& operator=(const OggFile&); 0299 0300 #ifdef HAVE_VORBIS 0301 /** 0302 * Read information about an Ogg/Vorbis file. 0303 * @param info file info to fill 0304 * @param fn file name 0305 * @return true if ok. 0306 */ 0307 bool readFileInfo(FileInfo& info, const QString& fn) const; 0308 #endif // HAVE_VORBIS 0309 };