| @@ -124,6 +124,15 @@ namespace Ids | |||
| DECLARE_ID (androidSDKPath); | |||
| DECLARE_ID (androidNDKPath); | |||
| DECLARE_ID (androidInternetNeeded); | |||
| DECLARE_ID (upImage); | |||
| DECLARE_ID (downImage); | |||
| DECLARE_ID (overImage); | |||
| DECLARE_ID (upOverlay); | |||
| DECLARE_ID (downOverlay); | |||
| DECLARE_ID (overOverlay); | |||
| DECLARE_ID (upOpacity); | |||
| DECLARE_ID (downOpacity); | |||
| DECLARE_ID (overOpacity); | |||
| const Identifier class_ ("class"); | |||
| const Identifier id_ ("id"); | |||
| @@ -132,7 +132,6 @@ class WMAudioReader : public AudioFormatReader | |||
| public: | |||
| WMAudioReader (InputStream* const input_) | |||
| : AudioFormatReader (input_, TRANS (wmFormatName)), | |||
| ok (false), | |||
| wmvCoreLib ("Wmvcore.dll"), | |||
| currentPosition (0), | |||
| bufferStart (0), bufferEnd (0) | |||
| @@ -143,8 +142,12 @@ public: | |||
| if (wmCreateSyncReader != nullptr) | |||
| { | |||
| CoInitialize (0); | |||
| HRESULT hr = wmCreateSyncReader (nullptr, WMT_RIGHT_PLAYBACK, wmSyncReader.resetAndGetPointerAddress()); | |||
| hr = wmSyncReader->OpenStream (new JuceIStream (*input)); | |||
| if (SUCCEEDED (hr)) | |||
| hr = wmSyncReader->OpenStream (new JuceIStream (*input)); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| @@ -153,7 +156,6 @@ public: | |||
| hr = wmSyncReader->SetReadStreamSamples (streamNum, false); | |||
| scanFileForDetails(); | |||
| ok = sampleRate > 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -170,7 +172,7 @@ public: | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| if (! ok) | |||
| if (sampleRate <= 0) | |||
| return false; | |||
| if (startSampleInFile != currentPosition) | |||
| @@ -245,8 +247,6 @@ public: | |||
| return true; | |||
| } | |||
| bool ok; | |||
| private: | |||
| DynamicLibrary wmvCoreLib; | |||
| ComSmartPtr<IWMSyncReader> wmSyncReader; | |||
| @@ -259,36 +259,49 @@ private: | |||
| ComSmartPtr<IWMHeaderInfo> wmHeaderInfo; | |||
| HRESULT hr = wmSyncReader.QueryInterface (wmHeaderInfo); | |||
| QWORD lengthInNanoseconds = 0; | |||
| WORD lengthOfLength = sizeof (lengthInNanoseconds); | |||
| WORD wmStreamNum = 0; | |||
| WMT_ATTR_DATATYPE wmAttrDataType; | |||
| hr = wmHeaderInfo->GetAttributeByName (&wmStreamNum, L"Duration", &wmAttrDataType, | |||
| (BYTE*) &lengthInNanoseconds, &lengthOfLength); | |||
| ComSmartPtr<IWMStreamConfig> wmStreamConfig; | |||
| ComSmartPtr<IWMProfile> wmProfile; | |||
| hr = wmSyncReader.QueryInterface (wmProfile); | |||
| hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); | |||
| ComSmartPtr<IWMMediaProps> wmMediaProperties; | |||
| hr = wmStreamConfig.QueryInterface (wmMediaProperties); | |||
| DWORD sizeMediaType; | |||
| hr = wmMediaProperties->GetMediaType (0, &sizeMediaType); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| QWORD lengthInNanoseconds = 0; | |||
| WORD lengthOfLength = sizeof (lengthInNanoseconds); | |||
| WORD streamNum = 0; | |||
| WMT_ATTR_DATATYPE wmAttrDataType; | |||
| hr = wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType, | |||
| (BYTE*) &lengthInNanoseconds, &lengthOfLength); | |||
| HeapBlock<WM_MEDIA_TYPE> mediaType; | |||
| mediaType.malloc (sizeMediaType, 1); | |||
| hr = wmMediaProperties->GetMediaType (mediaType, &sizeMediaType); | |||
| ComSmartPtr<IWMProfile> wmProfile; | |||
| hr = wmSyncReader.QueryInterface (wmProfile); | |||
| if (mediaType->majortype == WMMEDIATYPE_Audio) | |||
| { | |||
| const WAVEFORMATEX* const inputFormat = reinterpret_cast<WAVEFORMATEX*> (mediaType->pbFormat); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| ComSmartPtr<IWMStreamConfig> wmStreamConfig; | |||
| hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); | |||
| sampleRate = inputFormat->nSamplesPerSec; | |||
| numChannels = inputFormat->nChannels; | |||
| bitsPerSample = inputFormat->wBitsPerSample; | |||
| lengthInSamples = (lengthInNanoseconds * sampleRate) / 10000000; | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| ComSmartPtr<IWMMediaProps> wmMediaProperties; | |||
| hr = wmStreamConfig.QueryInterface (wmMediaProperties); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| DWORD sizeMediaType; | |||
| hr = wmMediaProperties->GetMediaType (0, &sizeMediaType); | |||
| HeapBlock<WM_MEDIA_TYPE> mediaType; | |||
| mediaType.malloc (sizeMediaType, 1); | |||
| hr = wmMediaProperties->GetMediaType (mediaType, &sizeMediaType); | |||
| if (mediaType->majortype == WMMEDIATYPE_Audio) | |||
| { | |||
| const WAVEFORMATEX* const inputFormat = reinterpret_cast<WAVEFORMATEX*> (mediaType->pbFormat); | |||
| sampleRate = inputFormat->nSamplesPerSec; | |||
| numChannels = inputFormat->nChannels; | |||
| bitsPerSample = inputFormat->wBitsPerSample; | |||
| lengthInSamples = (lengthInNanoseconds * sampleRate) / 10000000; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -316,7 +329,7 @@ AudioFormatReader* WindowsMediaAudioFormat::createReaderFor (InputStream* source | |||
| { | |||
| ScopedPointer<WindowsMediaCodec::WMAudioReader> r (new WindowsMediaCodec::WMAudioReader (sourceStream)); | |||
| if (r->ok) | |||
| if (r->sampleRate > 0) | |||
| return r.release(); | |||
| if (! deleteStreamIfOpeningFails) | |||
| @@ -46,6 +46,11 @@ String LocalisedStrings::translate (const String& text) const | |||
| return translations.getValue (text, text); | |||
| } | |||
| String LocalisedStrings::translate (const String& text, const String& resultIfNotFound) const | |||
| { | |||
| return translations.getValue (text, resultIfNotFound); | |||
| } | |||
| namespace | |||
| { | |||
| #if JUCE_CHECK_MEMORY_LEAKS | |||
| @@ -155,17 +160,34 @@ LocalisedStrings* LocalisedStrings::getCurrentMappings() | |||
| String LocalisedStrings::translateWithCurrentMappings (const String& text) | |||
| { | |||
| const SpinLock::ScopedLockType sl (currentMappingsLock); | |||
| return juce::translate (text); | |||
| } | |||
| if (currentMappings != nullptr) | |||
| return currentMappings->translate (text); | |||
| String LocalisedStrings::translateWithCurrentMappings (const char* text) | |||
| { | |||
| return juce::translate (String (text)); | |||
| } | |||
| return text; | |||
| String translate (const String& text) | |||
| { | |||
| return translate (text, text); | |||
| } | |||
| String LocalisedStrings::translateWithCurrentMappings (const char* text) | |||
| String translate (const char* const literal) | |||
| { | |||
| const String text (literal); | |||
| return translate (text, text); | |||
| } | |||
| String translate (const String& text, const String& resultIfNotFound) | |||
| { | |||
| return translateWithCurrentMappings (String (text)); | |||
| const SpinLock::ScopedLockType sl (currentMappingsLock); | |||
| const LocalisedStrings* const currentMappings = LocalisedStrings::getCurrentMappings(); | |||
| if (currentMappings != nullptr) | |||
| return currentMappings->translate (text, resultIfNotFound); | |||
| return resultIfNotFound; | |||
| } | |||
| @@ -29,18 +29,6 @@ | |||
| #include "juce_StringPairArray.h" | |||
| #include "../files/juce_File.h" | |||
| //============================================================================== | |||
| /** Used in the same way as the T(text) macro, this will attempt to translate a | |||
| string into a localised version using the LocalisedStrings class. | |||
| @see LocalisedStrings | |||
| */ | |||
| #define TRANS(stringLiteral) \ | |||
| juce::LocalisedStrings::translateWithCurrentMappings (stringLiteral) | |||
| //============================================================================== | |||
| /** | |||
| Used to convert strings to localised foreign-language versions. | |||
| @@ -149,11 +137,15 @@ public: | |||
| //============================================================================== | |||
| /** Attempts to look up a string and return its localised version. | |||
| If the string isn't found in the list, the original string will be returned. | |||
| */ | |||
| String translate (const String& text) const; | |||
| /** Attempts to look up a string and return its localised version. | |||
| If the string isn't found in the list, the resultIfNotFound string will be returned. | |||
| */ | |||
| String translate (const String& text, const String& resultIfNotFound) const; | |||
| /** Returns the name of the language specified in the translation file. | |||
| This is specified in the file using a line starting with "language:", e.g. | |||
| @@ -192,5 +184,31 @@ private: | |||
| JUCE_LEAK_DETECTOR (LocalisedStrings); | |||
| }; | |||
| //============================================================================== | |||
| #ifndef TRANS | |||
| /** Uses the LocalisedStrings class to translate the given string literal. | |||
| This macro is provided for backwards-compatibility, and just calls the translate() | |||
| function. In new code, it's recommended that you just call translate() directly | |||
| instead, and avoid using macros. | |||
| @see translate(), LocalisedStrings | |||
| */ | |||
| #define TRANS(stringLiteral) juce::translate (stringLiteral) | |||
| #endif | |||
| /** Uses the LocalisedStrings class to translate the given string literal. | |||
| @see LocalisedStrings | |||
| */ | |||
| String translate (const String& stringLiteral); | |||
| /** Uses the LocalisedStrings class to translate the given string literal. | |||
| @see LocalisedStrings | |||
| */ | |||
| String translate (const char* stringLiteral); | |||
| /** Uses the LocalisedStrings class to translate the given string literal. | |||
| @see LocalisedStrings | |||
| */ | |||
| String translate (const String& stringLiteral, const String& resultIfNotFound); | |||
| #endif // __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ | |||