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

refactor: 최종 리팩토링 #185

Draft
wants to merge 35 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1714d34
chore: 파일 분리, 변수명 변경, format 적용
psangwon62 Dec 2, 2024
ca5d334
refactor: 말풍선 셀 레이아웃 리팩토링
psangwon62 Dec 2, 2024
460ddbc
refactor: 프로필뷰 리팩
psangwon62 Dec 2, 2024
d4621e7
feat: 오디오 파형 분석기 구현
psangwon62 Dec 2, 2024
0ee2a64
refactor: 결과 뷰 조금 수정
psangwon62 Dec 2, 2024
f0c08dc
fix: 말풍선 다크모드 대응 수정
psangwon62 Dec 2, 2024
3f66d3b
feat: 말풍선에 waveform 이식을 위한 매개변수 및 변수 추가, 파일 분리
psangwon62 Dec 2, 2024
ee9b456
chore: Audioanalyzer 추가로 프로젝트 파일 변경
psangwon62 Dec 2, 2024
15e4457
refactor: resultTableView DiffableDataSource 임시 적용
Tltlbo Dec 4, 2024
37dcb6a
refactor: Model 부분 변수, 상수화 및 BubbleCell에 오류 나던 부분 수정
Tltlbo Dec 4, 2024
3838ec4
fix: 변수로 재수정
Tltlbo Dec 4, 2024
de867c6
refactor: 데이터 다운로드 Combine에서 async-await으로 변경
psangwon62 Dec 4, 2024
f35a09b
chore: 잘못 수정한 파일 이름 다시 수정
psangwon62 Dec 4, 2024
0f58863
chore: 더미 이미지 삭제
psangwon62 Dec 4, 2024
9cbcd55
chore: 필요없는 주석 삭제
psangwon62 Dec 4, 2024
0e93a27
refactor: 결과 fetch 로직 변경
psangwon62 Dec 4, 2024
4c67935
refactor: 모호한 함수명 변경, 허밍결과 뷰모델 extension으로 분리
psangwon62 Dec 4, 2024
7f3d89d
refactor: 허밍결과 뷰모델 함수분리
psangwon62 Dec 4, 2024
52b325f
refactor: 네비게이션 뒤로가기 버튼 로비 제외 house로 변경
psangwon62 Dec 4, 2024
e5f908a
refactor: 버튼 위치 조정
psangwon62 Dec 4, 2024
008a024
refactor: 로비뷰컨 변수 접근제어자 변경, 필요없는 코드 삭제
psangwon62 Dec 4, 2024
4575e8d
refactor: 로딩 뷰 아이콘 크기 축소
psangwon62 Dec 4, 2024
52b0325
fix: 로비에서 아바타 레이아웃 안잡히는 문제 해결
psangwon62 Dec 4, 2024
9393809
refactor: 모드 설명 폰트 확대
psangwon62 Dec 4, 2024
068d7eb
refactor: 허밍뷰가 뷰모델의 함수를 직접적으로 호출하지 않도록 변경
psangwon62 Dec 4, 2024
4163c50
refactor: 데이터 다운로드 레포 생성, Musicrepo 삭제
psangwon62 Dec 5, 2024
35ce242
refactor: 가이드 애니메이션 수정
psangwon62 Dec 5, 2024
8cb8f83
fix: 랜덤 음악 선택 Mainactor로 변경(보라오류 발생)
psangwon62 Dec 5, 2024
52bda5f
refactor: 네비게이션 바 컴포넌트 기본값되도록 수정
psangwon62 Dec 5, 2024
b1a42e6
refactor: 결과 말풍선 변경 상태 방식 변경
psangwon62 Dec 5, 2024
dfa0b3a
refactor: 말풍선 셀 리팩토링
psangwon62 Dec 5, 2024
fd9a5ee
feat: 버튼 활성화/비활성화 로직 추가
psangwon62 Dec 5, 2024
f2ab992
feat: 진폭 기능 말풍선에 붙이기
psangwon62 Dec 5, 2024
3fdb291
fix: 결과 음악 시작 타이밍 조정
psangwon62 Dec 5, 2024
6e1e59d
fix: 파형 업데이트 안 되는 문제 해결(야매)
psangwon62 Dec 5, 2024
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
54 changes: 54 additions & 0 deletions alsongDalsong/ASAudioKit/ASAudioAnalyzer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import AVFoundation
import Foundation

public enum ASAudioAnalyzer {
public static func analyze(data: Data, samplesCount: Int) async throws -> [CGFloat] {
let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".m4a")
try data.write(to: tempURL)
let file = try AVAudioFile(forReading: tempURL)

guard
let format = AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: file.fileFormat.sampleRate,
channels: file.fileFormat.channelCount,
interleaved: false
),
let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(file.length))
else {
return []
}

try file.read(into: buffer)
guard let floatChannelData = buffer.floatChannelData else {
return []
}

let frameLength = Int(buffer.frameLength)
let samples = Array(UnsafeBufferPointer(start: floatChannelData[0], count: frameLength))
var result = [CGFloat]()
let chunkedSamples = samples.chunked(into: samples.count / samplesCount)

for chunk in chunkedSamples {
let squaredSum = chunk.reduce(0) { $0 + $1 * $1 }
let averagePower = squaredSum / Float(chunk.count)
let decibels = 10 * log10(max(averagePower, Float.ulpOfOne))

let newAmplitude = 1.8 * pow(10.0, decibels / 20.0)
let clampedAmplitude = min(max(CGFloat(newAmplitude), 0), 1)
result.append(clampedAmplitude)
}

try? FileManager.default.removeItem(at: tempURL)

return result
}
}

extension Array {
func chunked(into size: Int) -> [[Element]] {
stride(from: 0, to: count, by: size).map {
Array(self[$0 ..< Swift.min($0 + size, count)])
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
1B7EB01B2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B7EB01A2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift */; };
1B7EB01C2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B7EB01A2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift */; };
4E8907C22CE2489A00D5B547 /* ASAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E89071E2CE23D1B00D5B547 /* ASAudioKit.framework */; platformFilter = ios; };
4EB1ED372CE88E500012FFBA /* ASAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E89071E2CE23D1B00D5B547 /* ASAudioKit.framework */; };
4EB1ED382CE88E500012FFBA /* ASAudioKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4E89071E2CE23D1B00D5B547 /* ASAudioKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
Expand Down Expand Up @@ -44,6 +46,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
1B7EB01A2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASAudioAnalyzer.swift; sourceTree = "<group>"; };
4E89071E2CE23D1B00D5B547 /* ASAudioKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ASAudioKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4E8907BE2CE2489A00D5B547 /* ASAudioKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ASAudioKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4EB1EC802CE7AA160012FFBA /* ASAudioDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ASAudioDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -121,6 +124,7 @@
4E8907142CE23D1A00D5B547 = {
isa = PBXGroup;
children = (
1B7EB01A2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift */,
4E8907AD2CE240D400D5B547 /* ASAudioKit */,
4E8907BF2CE2489A00D5B547 /* ASAudioKitTests */,
4EB1EC812CE7AA160012FFBA /* ASAudioDemo */,
Expand Down Expand Up @@ -300,6 +304,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1B7EB01C2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -314,6 +319,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1B7EB01B2CFDA83B00B2BE2A /* ASAudioAnalyzer.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public actor ASAudioPlayer: NSObject {
public var onPlaybackFinished: (@Sendable () async -> Void)?

/// 녹음파일을 재생하고 옵션에 따라 재생시간을 설정합니다.
public func startPlaying(data: Data, option: PlayType) {
public func startPlaying(data: Data, option: PlayType = .full) {
configureAudioSession()
do {
audioPlayer = try AVAudioPlayer(data: data)
Expand Down
2 changes: 1 addition & 1 deletion alsongDalsong/ASEntity/ASEntity/Answer.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Answer: Codable, Equatable {
public struct Answer: Codable, Equatable, Sendable, Hashable {
public var player: Player?
public var music: Music?
public var playlist: Playlist?
Expand Down
2 changes: 1 addition & 1 deletion alsongDalsong/ASEntity/ASEntity/Music.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Music: Codable, Equatable, Identifiable, Sendable {
public struct Music: Codable, Equatable, Identifiable, Sendable, Hashable {
public var id: String?
public var title: String?
public var artist: String?
Expand Down
2 changes: 1 addition & 1 deletion alsongDalsong/ASEntity/ASEntity/Player.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Player: Codable, Equatable, Identifiable {
public struct Player: Codable, Equatable, Identifiable, Sendable, Hashable {
public var id: String
public var avatarUrl: URL?
public var nickname: String?
Expand Down
2 changes: 1 addition & 1 deletion alsongDalsong/ASEntity/ASEntity/Playlist.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Playlist: Codable, Equatable {
public struct Playlist: Codable, Equatable, Sendable, Hashable {
public var artworkUrl: URL?
public var title: String?

Expand Down
2 changes: 1 addition & 1 deletion alsongDalsong/ASEntity/ASEntity/Record.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Record: Codable, Equatable {
public struct Record: Codable, Equatable, Sendable, Hashable {
public var player: Player?
public var recordOrder: UInt8?
public var fileUrl: URL?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public protocol SubmitsRepositoryProtocol {

public protocol AvatarRepositoryProtocol {
func getAvatarUrls() async throws -> [URL]
func getAvatarData(url: URL) async -> Data?
}

public protocol RoomActionRepositoryProtocol: Sendable {
Expand All @@ -61,15 +60,14 @@ public protocol RoomActionRepositoryProtocol: Sendable {
func resetGame() async throws -> Bool
}

public protocol MusicRepositoryProtocol {
func getMusicData(url: URL) async -> Data?
}

public protocol GameStateRepositoryProtocol {
func getGameState() -> AnyPublisher<GameState?, Never>
}

public protocol HummingResultRepositoryProtocol {
func getResult() -> AnyPublisher<[(answer: Answer, records: [ASEntity.Record], submit: Answer, recordOrder: UInt8)], Never>
func getRecordData(url: URL) -> Future<Data?, Error>
}

public protocol DataDownloadRepositoryProtocol {
func downloadData(url: URL) async -> Data?
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ import ASRepositoryProtocol
public final class AvatarRepository: AvatarRepositoryProtocol {
// TODO: - Container로 주입
private let storageManager: ASFirebaseStorageProtocol
private let networkManager: ASNetworkManagerProtocol

public init (
storageManager: ASFirebaseStorageProtocol,
networkManager: ASNetworkManagerProtocol
storageManager: ASFirebaseStorageProtocol
) {
self.storageManager = storageManager
self.networkManager = networkManager
}

public func getAvatarUrls() async throws -> [URL] {
Expand All @@ -24,14 +21,4 @@ public final class AvatarRepository: AvatarRepositoryProtocol {
throw error
}
}

public func getAvatarData(url: URL) async -> Data? {
do {
guard let endpoint = ResourceEndpoint(url: url) else { return nil }
let data = try await self.networkManager.sendRequest(to: endpoint, type: .none, body: nil, option: .both)
return data
} catch {
return nil
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ASNetworkKit
import ASRepositoryProtocol

public final class DataDownloadRepository: DataDownloadRepositoryProtocol {
private var networkManager: ASNetworkManagerProtocol

public init(networkManager: ASNetworkManagerProtocol) {
self.networkManager = networkManager
}

public func downloadData(url: URL) async -> Data? {
guard let endpoint = ResourceEndpoint(url: url) else { return nil }
do {
let data = try await networkManager.sendRequest(to: endpoint, type: .none, body: nil, option: .both)
return data
} catch {
return nil
}
}
}
Loading