Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ios handle apostrophes #29

Merged
merged 11 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions binding/ios/Orca-iOS.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'Orca-iOS'
s.module_name = 'Orca'
s.version = '0.2.1'
s.version = '0.2.2'
s.license = {:type => 'Apache 2.0'}
s.summary = 'iOS binding for Picovoice\'s Orca Text-to-Speech Engine.'
s.description =
Expand All @@ -18,7 +18,7 @@ Pod::Spec.new do |s|
DESC
s.homepage = 'https://github.com/Picovoice/orca/tree/main/binding/ios'
s.author = { 'Picovoice' => '[email protected]' }
s.source = { :git => "https://github.com/Picovoice/orca.git", :tag => "Orca-iOS-v0.2.1" }
s.source = { :git => "https://github.com/Picovoice/orca.git", :tag => "Orca-iOS-v0.2.2" }
s.ios.deployment_target = '13.0'
s.swift_version = '5.0'
s.vendored_frameworks = 'lib/ios/PvOrca.xcframework'
Expand Down
23 changes: 19 additions & 4 deletions binding/ios/Orca.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ public struct OrcaWord {
}
}

private func swapQuotes(_ text: String) -> String {
var output = text
output = output.replacingOccurrences(of: "’", with: "'")
output = output.replacingOccurrences(of: "‘", with: "'")
output = output.replacingOccurrences(of: "“", with: "\"")
output = output.replacingOccurrences(of: "”", with: "\"")
return output
}

/// iOS (Swift) binding for Orca Text-to-Speech engine. Provides a Swift interface to the Orca library.
public class Orca {

Expand Down Expand Up @@ -116,9 +125,11 @@ public class Orca {
var cNumSamples: Int32 = 0
var cPcm: UnsafeMutablePointer<Int16>?

let formattedText = swapQuotes(text)

let status = pv_orca_stream_synthesize(
stream,
text,
formattedText,
&cNumSamples,
&cPcm)
if status != PV_STATUS_SUCCESS {
Expand Down Expand Up @@ -228,7 +239,7 @@ public class Orca {
let messageStack = try getMessageStack()
throw pvStatusToOrcaError(validCharactersStatus, "Unable to get Orca valid characters", messageStack)
}
var validCharacters: Set<String> = []
var validCharacters: Set<String> = ["‘", "’", "“", "”"]
for i in 0..<cNumCharacters {
if let cString = cCharacters?.advanced(by: Int(i)).pointee {
let swiftString = String(cString: cString)
Expand Down Expand Up @@ -316,9 +327,11 @@ public class Orca {
var cNumAlignments: Int32 = 0
var cAlignments: UnsafeMutablePointer<UnsafeMutablePointer<pv_orca_word_alignment_t>?>?

let formattedText = swapQuotes(text)

let status = pv_orca_synthesize(
handle,
text,
formattedText,
cSynthesizeParams,
&cNumSamples,
&cPcm,
Expand Down Expand Up @@ -401,9 +414,11 @@ public class Orca {
var cNumAlignments: Int32 = 0
var cAlignments: UnsafeMutablePointer<UnsafeMutablePointer<pv_orca_word_alignment_t>?>?

let formattedText = swapQuotes(text)

let status = pv_orca_synthesize_to_file(
handle,
text,
formattedText,
cSynthesizeParams,
outputPath,
&cNumAlignments,
Expand Down
124 changes: 62 additions & 62 deletions binding/ios/OrcaAppTest/OrcaAppTest.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class OrcaAppTestUITests: BaseTest {
for orca in self.orcas {
XCTAssertGreaterThan(orca.validCharacters!.count, 0)
XCTAssert(orca.validCharacters!.contains(","))
XCTAssert(orca.validCharacters!.contains("‘"))
XCTAssert(orca.validCharacters!.contains("’"))
XCTAssert(orca.validCharacters!.contains("“"))
XCTAssert(orca.validCharacters!.contains("”"))
}
}

Expand Down Expand Up @@ -178,12 +182,71 @@ class OrcaAppTestUITests: BaseTest {
let audioFile = audioDir.appendingPathComponent("test.wav")

for orca in self.orcas {
try orca.synthesizeToFile(text: self.testData!.test_sentences.text, outputURL: audioFile)
let wordArrayFromURL = try orca.synthesizeToFile(
text: self.testData!.test_sentences.text, outputURL: audioFile)
XCTAssert(FileManager().fileExists(atPath: audioFile.path))
XCTAssertGreaterThan(wordArrayFromURL.count, 0)
try FileManager().removeItem(at: audioFile)

try orca.synthesizeToFile(text: self.testData!.test_sentences.text, outputPath: audioFile.path)
let wordArrayFromPath = try orca.synthesizeToFile(
text: self.testData!.test_sentences.text, outputPath: audioFile.path)
XCTAssert(FileManager().fileExists(atPath: audioFile.path))
XCTAssertGreaterThan(wordArrayFromPath.count, 0)
try FileManager().removeItem(at: audioFile)
}
}

let textQuotes =
"iOS uses different quotation marks for ‘single’ and “double” quotes."

func testStreamingQuotes() throws {
for orca in self.orcas {
let orcaStream = try orca.streamOpen()

var fullPcm = [Int16]()
for c in textQuotes {
if let pcm = try orcaStream.synthesize(text: String(c)) {
if !pcm.isEmpty {
fullPcm.append(contentsOf: pcm)
}
}
}

if let flushedPcm = try orcaStream.flush(), !flushedPcm.isEmpty {
fullPcm.append(contentsOf: flushedPcm)
}

orcaStream.close()
XCTAssertGreaterThan(fullPcm.count, 0)
}
}

func testSynthesizeQuotes() throws {
for orca in self.orcas {
let (pcm, wordArray) = try orca.synthesize(
text: textQuotes)
XCTAssertGreaterThan(pcm.count, 0)
XCTAssertGreaterThan(wordArray.count, 0)
}
}

func testSynthesizeToFileQuotes() throws {
let audioDir = try FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
let audioFile = audioDir.appendingPathComponent("test.wav")

for orca in self.orcas {
let wordArrayFromURL = try orca.synthesizeToFile(text: textQuotes, outputURL: audioFile)
XCTAssert(FileManager().fileExists(atPath: audioFile.path))
XCTAssertGreaterThan(wordArrayFromURL.count, 0)
try FileManager().removeItem(at: audioFile)

let wordArrayFromPath = try orca.synthesizeToFile(text: textQuotes, outputPath: audioFile.path)
XCTAssert(FileManager().fileExists(atPath: audioFile.path))
XCTAssertGreaterThan(wordArrayFromPath.count, 0)
try FileManager().removeItem(at: audioFile)
}
}
Expand Down
6 changes: 3 additions & 3 deletions binding/ios/OrcaAppTest/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ source 'https://cdn.cocoapods.org/'
platform :ios, '13.0'

target 'OrcaAppTest' do
pod 'Orca-iOS', '~> 0.2.1'
pod 'Orca-iOS', '~> 0.2.2'
end

target 'OrcaAppTestUITests' do
pod 'Orca-iOS', '~> 0.2.1'
pod 'Orca-iOS', '~> 0.2.2'
end

target 'PerformanceTest' do
pod 'Orca-iOS', '~> 0.2.1'
pod 'Orca-iOS', '~> 0.2.2'
end
8 changes: 4 additions & 4 deletions binding/ios/OrcaAppTest/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
PODS:
- Orca-iOS (0.2.1)
- Orca-iOS (0.2.2)

DEPENDENCIES:
- Orca-iOS (~> 0.2.1)
- Orca-iOS (~> 0.2.2)

SPEC REPOS:
trunk:
- Orca-iOS

SPEC CHECKSUMS:
Orca-iOS: f6b6124d78189e26c8c0457022a5948217ebe2d3
Orca-iOS: 567ca0e53671d8fc28ba15338db8fe4ff5101d8d

PODFILE CHECKSUM: c74fc8347aa5171d01ba9ce86c96a401037847d4
PODFILE CHECKSUM: 2deb98490df78cf895d797180dcfeccea4f2ad25

COCOAPODS: 1.15.2
42 changes: 21 additions & 21 deletions demo/ios/OrcaDemo/OrcaDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 60;
objects = {

/* Begin PBXBuildFile section */
Expand All @@ -13,7 +13,7 @@
02A1195F268D3FD600A2AC99 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A1195E268D3FD600A2AC99 /* ViewModel.swift */; };
1E001B682B76FFE700D8E72D /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E001B672B76FFE700D8E72D /* AudioPlayer.swift */; };
1E001B6A2B7D451200D8E72D /* orca_params_female.pv in Resources */ = {isa = PBXBuildFile; fileRef = 1E001B692B7D451200D8E72D /* orca_params_female.pv */; };
B218600C461D96EA568B6D6C /* libPods-OrcaDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E91B80C84BF594FCF1FCBD /* libPods-OrcaDemo.a */; };
93BE66087E58F64A2193D44C /* libPods-OrcaDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6293833704AEC548A02FB651 /* libPods-OrcaDemo.a */; };
E125E1892BE99DCA008B6D56 /* AtomicBool.swift in Sources */ = {isa = PBXBuildFile; fileRef = E125E1882BE99DCA008B6D56 /* AtomicBool.swift */; };
E1C5A45F2BE587A2002C0C40 /* AudioPlayerStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C5A45E2BE587A2002C0C40 /* AudioPlayerStream.swift */; };
/* End PBXBuildFile section */
Expand All @@ -25,11 +25,11 @@
02A1194C268D39AB00A2AC99 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
02A11951268D39AB00A2AC99 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
02A1195E268D3FD600A2AC99 /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = "<group>"; };
1C5DAA8ED5D246C3A58AA45B /* Pods-OrcaDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OrcaDemo.release.xcconfig"; path = "Target Support Files/Pods-OrcaDemo/Pods-OrcaDemo.release.xcconfig"; sourceTree = "<group>"; };
1E001B672B76FFE700D8E72D /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = "<group>"; };
1E001B692B7D451200D8E72D /* orca_params_female.pv */ = {isa = PBXFileReference; lastKnownFileType = file; name = orca_params_female.pv; path = ../../../../lib/common/orca_params_female.pv; sourceTree = "<group>"; };
2C3AE1B63A5DD37711F6DD7E /* Pods-OrcaDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OrcaDemo.debug.xcconfig"; path = "Target Support Files/Pods-OrcaDemo/Pods-OrcaDemo.debug.xcconfig"; sourceTree = "<group>"; };
97762F0F3B18F16DC68C5D67 /* Pods-OrcaDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OrcaDemo.release.xcconfig"; path = "Target Support Files/Pods-OrcaDemo/Pods-OrcaDemo.release.xcconfig"; sourceTree = "<group>"; };
A9E91B80C84BF594FCF1FCBD /* libPods-OrcaDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OrcaDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3B38AA40E88807F9C21BFD02 /* Pods-OrcaDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OrcaDemo.debug.xcconfig"; path = "Target Support Files/Pods-OrcaDemo/Pods-OrcaDemo.debug.xcconfig"; sourceTree = "<group>"; };
6293833704AEC548A02FB651 /* libPods-OrcaDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OrcaDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
E125E1882BE99DCA008B6D56 /* AtomicBool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicBool.swift; sourceTree = "<group>"; };
E1C5A45E2BE587A2002C0C40 /* AudioPlayerStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerStream.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand All @@ -39,7 +39,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B218600C461D96EA568B6D6C /* libPods-OrcaDemo.a in Frameworks */,
93BE66087E58F64A2193D44C /* libPods-OrcaDemo.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -52,7 +52,7 @@
02A11947268D39A700A2AC99 /* OrcaDemo */,
02A11946268D39A700A2AC99 /* Products */,
8DB92FF3DC81AB04D3FF7242 /* Pods */,
4374BA75AB06EC0D059377CD /* Frameworks */,
D4BC0C682CB4645A73894BC8 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -80,21 +80,21 @@
path = OrcaDemo;
sourceTree = "<group>";
};
4374BA75AB06EC0D059377CD /* Frameworks */ = {
8DB92FF3DC81AB04D3FF7242 /* Pods */ = {
isa = PBXGroup;
children = (
A9E91B80C84BF594FCF1FCBD /* libPods-OrcaDemo.a */,
3B38AA40E88807F9C21BFD02 /* Pods-OrcaDemo.debug.xcconfig */,
1C5DAA8ED5D246C3A58AA45B /* Pods-OrcaDemo.release.xcconfig */,
);
name = Frameworks;
path = Pods;
sourceTree = "<group>";
};
8DB92FF3DC81AB04D3FF7242 /* Pods */ = {
D4BC0C682CB4645A73894BC8 /* Frameworks */ = {
isa = PBXGroup;
children = (
2C3AE1B63A5DD37711F6DD7E /* Pods-OrcaDemo.debug.xcconfig */,
97762F0F3B18F16DC68C5D67 /* Pods-OrcaDemo.release.xcconfig */,
6293833704AEC548A02FB651 /* libPods-OrcaDemo.a */,
);
path = Pods;
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
Expand All @@ -104,11 +104,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 02A11954268D39AB00A2AC99 /* Build configuration list for PBXNativeTarget "OrcaDemo" */;
buildPhases = (
E5EA3B129B59D3DF4752D82D /* [CP] Check Pods Manifest.lock */,
953F197786B352AA828626D7 /* [CP] Check Pods Manifest.lock */,
02A11941268D39A700A2AC99 /* Sources */,
02A11942268D39A700A2AC99 /* Frameworks */,
02A11943268D39A700A2AC99 /* Resources */,
E85A144184F1D605DB772089 /* [CP] Embed Pods Frameworks */,
C4DE16407A77E6DE174EE4DB /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand All @@ -134,7 +134,7 @@
};
};
buildConfigurationList = 02A11940268D39A700A2AC99 /* Build configuration list for PBXProject "OrcaDemo" */;
compatibilityVersion = "Xcode 9.3";
compatibilityVersion = "Xcode 15.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Expand Down Expand Up @@ -164,7 +164,7 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
E5EA3B129B59D3DF4752D82D /* [CP] Check Pods Manifest.lock */ = {
953F197786B352AA828626D7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -186,7 +186,7 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E85A144184F1D605DB772089 /* [CP] Embed Pods Frameworks */ = {
C4DE16407A77E6DE174EE4DB /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand Down Expand Up @@ -340,7 +340,7 @@
};
02A11955268D39AB00A2AC99 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2C3AE1B63A5DD37711F6DD7E /* Pods-OrcaDemo.debug.xcconfig */;
baseConfigurationReference = 3B38AA40E88807F9C21BFD02 /* Pods-OrcaDemo.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
Expand All @@ -363,7 +363,7 @@
};
02A11956268D39AB00A2AC99 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 97762F0F3B18F16DC68C5D67 /* Pods-OrcaDemo.release.xcconfig */;
baseConfigurationReference = 1C5DAA8ED5D246C3A58AA45B /* Pods-OrcaDemo.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
Expand Down
6 changes: 2 additions & 4 deletions demo/ios/OrcaDemo/OrcaDemo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,8 @@ struct ContentView: View {
.font(.title3)
.background(lightGray)
.foregroundColor(Color.black)
.onChange(of: text) { newValue in
let updatedText = String(
newValue.prefix(Int(exactly: viewModel.maxCharacterLimit)!))
text = updatedText.replacingOccurrences(of: "’", with: "'")
.onChange(of: text) { _ in
text = String(text.prefix(Int(exactly: viewModel.maxCharacterLimit)!))
viewModel.isValid(text: text)
}
.disabled(viewModel.state == .PLAYING)
Expand Down
2 changes: 1 addition & 1 deletion demo/ios/OrcaDemo/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ source 'https://cdn.cocoapods.org/'
platform :ios, '13.0'

target 'OrcaDemo' do
pod 'Orca-iOS', '~> 0.2.1'
pod 'Orca-iOS', '~> 0.2.2'
end
8 changes: 4 additions & 4 deletions demo/ios/OrcaDemo/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
PODS:
- Orca-iOS (0.2.1)
- Orca-iOS (0.2.2)

DEPENDENCIES:
- Orca-iOS (~> 0.2.1)
- Orca-iOS (~> 0.2.2)

SPEC REPOS:
trunk:
- Orca-iOS

SPEC CHECKSUMS:
Orca-iOS: f6b6124d78189e26c8c0457022a5948217ebe2d3
Orca-iOS: 567ca0e53671d8fc28ba15338db8fe4ff5101d8d

PODFILE CHECKSUM: 652a0a00a9d97df5db1dd9d329fcda8f33faf935
PODFILE CHECKSUM: 118fa8c1767dd3edcc2ec366a16ab74191c6176c

COCOAPODS: 1.15.2
Loading