Home | History | Annotate | Download | only in BroadcastRadio
      1 /**
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "BroadcastRadioService.regions.jni"
     18 #define LOG_NDEBUG 0
     19 
     20 #include "regions.h"
     21 
     22 #include <broadcastradio-utils/Utils.h>
     23 #include <utils/Log.h>
     24 
     25 namespace android {
     26 namespace server {
     27 namespace BroadcastRadio {
     28 namespace regions {
     29 
     30 namespace utils = hardware::broadcastradio::V1_1::utils;
     31 
     32 using hardware::hidl_vec;
     33 
     34 using V1_0::Band;
     35 using V1_0::BandConfig;
     36 using V1_0::Deemphasis;
     37 using V1_0::Rds;
     38 
     39 class RegionalBandDefinition {
     40 public:
     41     std::vector<Region> mRegions;
     42     std::vector<Band> mTypes;
     43     uint32_t mLowerLimit;
     44     uint32_t mUpperLimit;
     45     uint32_t mSpacing;
     46 
     47     Deemphasis mFmDeemphasis = {};
     48     Rds mFmRds = Rds::NONE;
     49 
     50     bool fitsInsideBand(const BandConfig &bandConfig) const;
     51     std::vector<RegionalBandConfig> withConfig(BandConfig bandConfig) const;
     52 };
     53 
     54 static const RegionalBandDefinition kKnownRegionConfigs[] = {
     55     {
     56         { Region::ITU_1 },
     57         { Band::FM },
     58         87500,
     59         108000,
     60         100,
     61         Deemphasis::D50,
     62         Rds::WORLD,
     63     },
     64     {
     65         { Region::ITU_2 },
     66         { Band::FM, Band::FM_HD },
     67         87700,
     68         107900,
     69         200,
     70         Deemphasis::D75,
     71         Rds::US,
     72     },
     73     {
     74         { Region::OIRT },
     75         { Band::FM },
     76         65800,
     77         74000,
     78         10,
     79         Deemphasis::D50,
     80         Rds::WORLD,
     81     },
     82     {
     83         { Region::JAPAN },
     84         { Band::FM },
     85         76000,
     86         90000,
     87         100,
     88         Deemphasis::D50,
     89         Rds::WORLD,
     90     },
     91     {
     92         { Region::KOREA },
     93         { Band::FM },
     94         87500,
     95         108000,
     96         100,
     97         Deemphasis::D75,
     98         Rds::WORLD,
     99     },
    100     {  // AM LW
    101         { Region::ITU_1, Region::OIRT, Region::JAPAN, Region::KOREA },
    102         { Band::AM },
    103         153,
    104         282,
    105         9,
    106     },
    107     {  // AM MW
    108         { Region::ITU_1, Region::OIRT, Region::JAPAN, Region::KOREA },
    109         { Band::AM },
    110         531,
    111         1620,
    112         9,
    113     },
    114     {  // AM SW
    115         { Region::ITU_1, Region::OIRT, Region::JAPAN, Region::KOREA },
    116         { Band::AM },
    117         2300,
    118         26100,
    119         5,
    120     },
    121     {  // AM LW ITU2
    122         { Region::ITU_2 },
    123         { Band::AM, Band::AM_HD },
    124         153,
    125         279,
    126         9,
    127     },
    128     {  // AM MW ITU2
    129         { Region::ITU_2 },
    130         { Band::AM, Band::AM_HD },
    131         530,
    132         1700,
    133         10,
    134     },
    135     {  // AM SW ITU2
    136         { Region::ITU_2 },
    137         { Band::AM, Band::AM_HD },
    138         2300,
    139         26100,
    140         5,
    141     },
    142 };
    143 
    144 bool RegionalBandDefinition::fitsInsideBand(const BandConfig &bandConfig) const {
    145     if (std::find(mTypes.begin(), mTypes.end(), bandConfig.type) == mTypes.end()) return false;
    146     if (mLowerLimit < bandConfig.lowerLimit) return false;
    147     if (mUpperLimit > bandConfig.upperLimit) return false;
    148     auto&& spacings = bandConfig.spacings;
    149     if (std::find(spacings.begin(), spacings.end(), mSpacing) == spacings.end()) return false;
    150     if (utils::isFm(bandConfig.type)) {
    151         if (0 == (mFmDeemphasis & bandConfig.ext.fm.deemphasis)) return false;
    152     }
    153 
    154     return true;
    155 }
    156 
    157 std::vector<RegionalBandConfig> RegionalBandDefinition::withConfig(BandConfig config) const {
    158     config.lowerLimit = mLowerLimit;
    159     config.upperLimit = mUpperLimit;
    160     config.spacings = hidl_vec<uint32_t>({ mSpacing });
    161     if (utils::isFm(config.type)) {
    162         auto&& fm = config.ext.fm;
    163         fm.deemphasis = mFmDeemphasis;
    164         fm.rds = static_cast<Rds>(mFmRds & fm.rds);
    165     }
    166 
    167     std::vector<RegionalBandConfig> configs;
    168     for (auto region : mRegions) {
    169         configs.push_back({region, config});
    170     }
    171 
    172     return configs;
    173 }
    174 
    175 std::vector<RegionalBandConfig> mapRegions(const hidl_vec<BandConfig>& bands) {
    176     ALOGV("%s", __func__);
    177 
    178     std::vector<RegionalBandConfig> out;
    179 
    180     for (auto&& regionalBand : kKnownRegionConfigs) {
    181         for (auto&& tunerBand : bands) {
    182             if (regionalBand.fitsInsideBand(tunerBand)) {
    183                 auto mapped = regionalBand.withConfig(tunerBand);
    184                 out.insert(out.end(), mapped.begin(), mapped.end());
    185             }
    186         }
    187     }
    188 
    189     ALOGI("Mapped %zu tuner bands to %zu regional bands", bands.size(), out.size());
    190     return out;
    191 }
    192 
    193 } // namespace regions
    194 } // namespace BroadcastRadio
    195 } // namespace server
    196 } // namespace android
    197